LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKI2lmbmRlZiBURVNUQVBQX0hYWAojZGVmaW5lIFRFU1RBUFBfSFhYCgojaW5jbHVkZSA8YmFzaWMvc2Jtb2QuaHh4PgojaW5jbHVkZSA8YmFzaWMvdGVzdHRvb2wuaHh4PgoKY2xhc3MgQ29tbXVuaWNhdGlvbkxpbms7CmNsYXNzIENvbW11bmljYXRpb25NYW5hZ2VyQ2xpZW50VmlhU29ja2V0VFQ7CmNsYXNzIENOYW1lczsKY2xhc3MgQ29udHJvbEl0ZW1VSWQ7CmNsYXNzIENSZXZOYW1lczsKLy9jbGFzcyBTYnhUcmFuc3BvcnRWYXJpYWJsZVJlZjsKY2xhc3MgQ29udHJvbHNSZWY7CmNsYXNzIENtZFN0cmVhbTsKY2xhc3MgRmxvYXRpbmdMb2FkQ29uZjsKY2xhc3MgVGVzdFRvb2xPYmo7CmNsYXNzIENvbnRyb2xEZWY7CgpjbGFzcyBTYnhUcmFuc3BvcnRNZXRob2Q7CmNsYXNzIEFwcGxpY2F0aW9uOwoKY2xhc3MgU290U3RvcmFnZTsKCmNsYXNzIEltcGxUZXN0VG9vbE9iajsKY2xhc3MgTXlCYXNpYzsKCmNsYXNzIEVycm9yRW50cnkKewpwdWJsaWM6CglFcnJvckVudHJ5KHNhbF91TG9uZyBuTnIsIFN0cmluZyBhU3RyID0gU3RyaW5nKCkpIDogbkVycm9yKG5OciksYVRleHQoYVN0ciksbkxpbmUoMCksbkNvbDEoMCksbkNvbDIoMCkge30KCUVycm9yRW50cnkoc2FsX3VMb25nIG5OciwgU3RyaW5nIGFTdHIsIHh1Yl9TdHJMZW4gbCwgeHViX1N0ckxlbiBjMSwgeHViX1N0ckxlbiBjMiApCgkJOiBuRXJyb3Iobk5yKSxhVGV4dChhU3RyKSxuTGluZShsKSxuQ29sMShjMSksbkNvbDIoYzIpIHt9CglzYWxfdUxvbmcgbkVycm9yOwoJU3RyaW5nIGFUZXh0OwoJeHViX1N0ckxlbiBuTGluZTsKCXh1Yl9TdHJMZW4gbkNvbDE7Cgl4dWJfU3RyTGVuIG5Db2wyOwp9OwoKU1ZfREVDTF9QVFJBUlJfREVMKENFcnJvcnMsIEVycm9yRW50cnkqLCAxLCAxKQoKc3RydWN0IENvbnRyb2xEZWZMb2FkIHsKCWNvbnN0IGNoYXIqIEt1cnpuYW1lOwoJc2FsX3VMb25nIG5VSWQ7Cn07CgpjbGFzcyBUZXN0VG9vbE9iajogcHVibGljIFNieE9iamVjdAp7CglmcmllbmQgY2xhc3MgVFRCYXNpYzsKCWZyaWVuZCBjbGFzcyBDb250cm9sczsKcHVibGljOgoJVGVzdFRvb2xPYmooIFN0cmluZyBhTmFtZSwgU3RyaW5nIGFGaWxlUGF0aCApOwkJLy8gQWxsZSBEYXRlaWVuIGluIEZpbGVQYXRoLCBLZWluIElQQwoJVGVzdFRvb2xPYmooIFN0cmluZyBhTmFtZSwgTXlCYXNpYyogcEJhcyApOwkvLyBQZmFkZSBhdXMgSU5JLCBJUEMgYmVudXR6ZW4KCX5UZXN0VG9vbE9iaigpOwoJdm9pZCBMb2FkSW5pRmlsZSgpOwkJCQkvLyBMYWRlbiBkZXIgSW5pRWluc3RlbGx1bmdlbiwgZGllIGR1cmNoIGRlbiBDb25maWdEaWFsb2cgZ2XkbmRlcnQgd2VyZGVuIGv2bm5lbgoJdm9pZCBEZWJ1Z0ZpbmROb0Vycm9ycyggc2FsX0Jvb2wgYkRlYnVnRmluZE5vRXJyb3JzICk7Cgpwcml2YXRlOgoJc2FsX0Jvb2wgYldhc1ByZWNvbXBpbGVyRXJyb3I7CS8vIFRydWUgd2VubiBiZWltIGxldHp0ZW4gUHJlY29tcGlsZSBlaW4gRmVobGVyIGF1ZnRyYXQKCXNhbF9Cb29sIENFcnJvciggc2FsX3VMb25nLCBjb25zdCBTdHJpbmcmLCB4dWJfU3RyTGVuLCB4dWJfU3RyTGVuLCB4dWJfU3RyTGVuICk7Cgl2b2lkIENhbGNQb3NpdGlvbiggU3RyaW5nIGNvbnN0ICZhU291cmNlLCB4dWJfU3RyTGVuIG5Qb3MsIHh1Yl9TdHJMZW4gJmwsIHh1Yl9TdHJMZW4gJmMgKTsKCXh1Yl9TdHJMZW4gSW1wbFNlYXJjaCggY29uc3QgU3RyaW5nICZhU291cmNlLCBjb25zdCB4dWJfU3RyTGVuIG5TdGFydCwgY29uc3QgeHViX1N0ckxlbiBuRW5kLCBjb25zdCBTdHJpbmcgJmFTZWFyY2gsIGNvbnN0IHh1Yl9TdHJMZW4gblNlYXJjaFN0YXJ0ID0gMCApOwoJeHViX1N0ckxlbiBQcmVDb21waWxlUGFydCggU3RyaW5nICZhU291cmNlLCB4dWJfU3RyTGVuIG5TdGFydCwgeHViX1N0ckxlbiBuRW5kLCBTdHJpbmcgYUZpbmFsRXJyb3JMYWJlbCwgc2FsX3VJbnQxNiAmbkxhYmVsQ291bnQgKTsKCXZvaWQgUHJlQ29tcGlsZURpc3BhdGNoUGFydHMoIFN0cmluZyAmYVNvdXJjZSwgU3RyaW5nIGFTdGFydCwgU3RyaW5nIGFFbmQsIFN0cmluZyBhRmluYWxMYWJsZSApOwpwdWJsaWM6CglTdHJpbmcgR2V0UmV2aXNpb24oU3RyaW5nIGNvbnN0ICZhU291cmNlSW4pOwkvLyBmaW5kIFJldmlzaW9uIGluIHRoZSBzb3VyY2Vjb2RlCglTdHJpbmcgUHJlQ29tcGlsZShTdHJpbmcgY29uc3QgJmFTb3VyY2VJbik7CS8vIHRyeSBjYXRjaDsgdGVzdGNhc2UgZW5kY2FzZSAuLgoJc2FsX0Jvb2wgV2FzUHJlY29tcGlsZXJFcnJvcigpOwkvLyBUcnVlIHdlbm4gYmVpbSBsZXR6dGVuIFByZWNvbXBpbGUgZWluIEZlaGxlciBhdWZ0cmF0Cgl2b2lkCQkJU0ZYX05PVElGWSggU2Z4QnJvYWRjYXN0ZXImLCBjb25zdCBUeXBlSWQmLCBjb25zdCBTZnhIaW50JiBySGludCwgY29uc3QgVHlwZUlkJiApOwoJdmlydHVhbCBTYnhWYXJpYWJsZSogRmluZCggY29uc3QgU3RyaW5nJiwgU2J4Q2xhc3NUeXBlICk7Ci8vCVN0cmluZyBhS2V5UGx1c0NsYXNzZXM7CQkvLyBQZmFkIGb8ciBrZXljb2RlcyAmIGNsYXNzZXMgJiByZXNfdHlwZSAoQXVzIENvbmZpZ2RhdGVpKQoJREVDTF9MSU5LKCBSZXR1cm5SZXN1bHRzTGluaywgQ29tbXVuaWNhdGlvbkxpbmsqICk7CglzYWxfQm9vbAkJCVJldHVyblJlc3VsdHMoIFN2U3RyZWFtICpwSW4gKTsJLy8gUvxja2xpZWZlcnVuZyBkZXMgQW50d29ydHN0cmVhbXMg/GJlciBJUEMgb2RlciBUQ1AvSVAgb2RlciBkaXJla3QKCgl2b2lkCQkJU2V0TG9nSGRsKCBjb25zdCBMaW5rJiByTGluayApIHsgYUxvZ0hkbCA9IHJMaW5rOyB9Cgljb25zdCBMaW5rJgkJR2V0TG9nSGRsKCkgY29uc3QgeyByZXR1cm4gYUxvZ0hkbDsgfQoKCXZvaWQJCQlTZXRXaW5JbmZvSGRsKCBjb25zdCBMaW5rJiByTGluayApIHsgYVdpbkluZm9IZGwgPSByTGluazsgfQoJY29uc3QgTGluayYJCUdldFdpbkluZm9IZGwoKSBjb25zdCB7IHJldHVybiBhV2luSW5mb0hkbDsgfQoKCXZvaWQJCQlTZXRNb2R1bGVXaW5FeGlzdHNIZGwoIGNvbnN0IExpbmsmIHJMaW5rICkgeyBhTW9kdWxlV2luRXhpc3RzSGRsID0gckxpbms7IH0KCWNvbnN0IExpbmsmCQlHZXRNb2R1bGVXaW5FeGlzdHNIZGwoKSBjb25zdCB7IHJldHVybiBhTW9kdWxlV2luRXhpc3RzSGRsOyB9CgoJdm9pZAkJCVNldENFcnJvckhkbCggY29uc3QgTGluayYgckxpbmsgKSB7IGFDRXJyb3JIZGwgPSByTGluazsgfQoJY29uc3QgTGluayYJCUdldENFcnJvckhkbCgpIGNvbnN0IHsgcmV0dXJuIGFDRXJyb3JIZGw7IH0KCgl2b2lkCQkJU2V0V3JpdGVTdHJpbmdIZGwoIGNvbnN0IExpbmsmIHJMaW5rICkgeyBhV3JpdGVTdHJpbmdIZGwgPSByTGluazsgfQoJY29uc3QgTGluayYJCUdldFdyaXRlU3RyaW5nSGRsKCkgY29uc3QgeyByZXR1cm4gYVdyaXRlU3RyaW5nSGRsOyB9CgoJU2Z4QnJvYWRjYXN0ZXImIEdldFRUQnJvYWRjYXN0ZXIoKTsKCnByaXZhdGU6CglJbXBsVGVzdFRvb2xPYmogKnBJbXBsOwkJLy8gQWxsZXMgd2FzIHZvbiBkZXIgSW1wbGVtZW50YXRpb24gYWJo5G5ndAoJc3RhdGljIGNvbnN0IENFcnJvcnMqIEdldEZlaGxlckxpc3RlKCkgeyByZXR1cm4gcEZlaGxlckxpc3RlOyB9CglzYWxfQm9vbCBiVXNlSVBDOwoJTGluayBhTG9nSGRsOwkJCQkvLyBadW0gTG9nZW4gZGVyIEZlaGxlcm1lbGR1bmdlbiBpbSBUZXN0dG9vbAoJTGluayBhV2luSW5mb0hkbDsJCQkvLyBBbnplaWdlbiBkZXIgV2luZG93cy9Db250cm9scyBkZXIgenUgdGVzdGVuZGVuIEFwcAoJTGluayBhTW9kdWxlV2luRXhpc3RzSGRsOwkvLyBQcvxmdCBvYiBkYXMgTW9kdWwgc2Nob24gaW0gRWRpdG9yIGdlbGFkZW4gaXN0CglMaW5rIGFDRXJyb3JIZGw7CQkJLy8gTWVsZGVuIHZvbiBDb21waWxlcmVycm9yCiAgICBMaW5rIGFXcml0ZVN0cmluZ0hkbDsgICAgICAgLy8gU2NocmVpYmVuIHZvbiB0ZXh0IChlLmcuIE1ha3JvUmVjb3JkZXIpCglzYWxfQm9vbCBiUmV0dXJuT0s7CQkJCS8vIEJyaWNodCBXYWl0Rm9yQW5zd2VyIGFiCglDUmV2TmFtZXMgKnBTaG9ydE5hbWVzOwkJLy8gQWt0dWVsbCB2ZXJ3ZW5kZXRlIENvbnRyb2xzLCB6dXIgZ2V3aW5udW5nIGRlcyBOYW1lbnMgYXVzIEZlaGxlcm1lbGR1bmcKCXNhbF91TG9uZyBuU2VxdWVuY2U7CQkJLy8gU2VxdWVuY2UgdW0gQW50d29ydCB1bmQgQW5mcmFnZSB6dSBzeW5jcm9uaXNpZXJlbgoJcnRsOjpPU3RyaW5nIGFOZXh0UmV0dXJuSWQ7CS8vIElkIGRlcyBSZXR1cm53ZXJ0ZXMgaS5lLiBVSWQKICAgIHZvaWQgUmVwbGFjZU51bWJlcnMoU3RyaW5nICZhVGV4dCk7CS8vIFphaGxlbiBpbSBTdHJpbmcgbWl0IHNwZXppZWxsZW0gRm9ybWF0IGluIE5hbWVuIHVtd2FuZGVsbgoKICAgIFN0cmluZyBhTGFzdFJlY29yZGVkS29udGV4dDsvLyAgS2VlcHMgdGhlIGxhc3Qga29udGV4dCByZWNvcmRlZCBieSB0aGUgTWFjcm8gUmVjb3JkZXIKCiNkZWZpbmUgRkxBVCBzYWxfVHJ1ZQoJU3RyaW5nIFByb2dQYXRoOwkJCS8vIERhdGVpbmFtZSBkZXIgenUgVGVzdGVuZGVuIEFQUDsgR2VzZXR6dCD8YmVyIFN0YXJ0CglTdHJpbmcgYUxvZ0ZpbGVOYW1lOwkJLy8gTW9tZW50YW5lciBMb2dmaWxlbmFtZSAoV2llIFByb2dyYW1tZGF0ZWkgYWJlciBtaXQgLnJlcykKCXNhbF9Cb29sIElzQmxvY2s7CQkJCS8vIElubmVyaGFsYiBCZWdpbi9FbmRCbG9jawoJc2FsX0Jvb2wgU2luZ2xlQ29tbWFuZEJsb2NrOwkvLyBJbXBsaXppdCB1bSBqZWRlcyBrb21tYW5kbyBlaW4gQmVnaW4vRW5kQmxvY2sKCUNtZFN0cmVhbSAqSW47CgoJdm9pZCBBZGROYW1lKFN0cmluZyAmYUJpc2hlciwgU3RyaW5nICZhTmV1ICk7CS8vIE5hbWUgZXZlbnR1ZWxsIG1pdCAvIGFuaORuZ2VuCgl2b2lkIEFkZFRvTGlzdEJ5TnIoIENOYW1lcyAqJnBDb250cm9scywgQ29udHJvbEl0ZW1VSWQgKiZwTmV3SXRlbSApOwkvLwoJQ05hbWVzICptX3BDb250cm9sczsKCUNOYW1lcyAqbV9wTmFtZUtvbnRleHQ7CQkvLyBaZWlndCBhdWYgZGVuIGFrdHVlbGxlbiBOYW1lbnNrb250ZXh0LCBkZXIg/GJlciAnS29udGV4dCcgZ2VzZXR6dCB3dXJkZQoJQ05hbWVzICptX3BTSWRzOwoJQ05hbWVzICptX3BSZXZlcnNlU2xvdHM7CQkvLyBTbG90cyBtaXQgS3Vyem5hbWVuIG5hY2ggTnVtbWVyCglDTmFtZXMgKm1fcFJldmVyc2VDb250cm9sczsJLy8gQ29udHJvbHMgbWl0IEt1cnpuYW1lbiBuYWNoIE51bW1lcgoJQ05hbWVzICptX3BSZXZlcnNlQ29udHJvbHNTb247Ly8gQ29udHJvbHMgbWl0IEt1cnpuYW1lbiBuYWNoIE51bW1lciBuYWNoIEZlbnN0ZXJuIChTb24pCglDTmFtZXMgKm1fcFJldmVyc2VVSWRzOwkJLy8gTGFuZ25hbWVuIG5hY2ggTnVtbWVyCgoKCXNhbF91SW50MTYgbk15VmFyOwkJCQkvLyBXaWV2aWVsdGUgVmFyIGF1cyBQb29sIGlzdCBkcmFuCgoJdm9pZCBJbml0VGVzdFRvb2xPYmooKTsKCUNvbW11bmljYXRpb25NYW5hZ2VyQ2xpZW50VmlhU29ja2V0VFQgKnBDb21tdW5pY2F0aW9uTWFuYWdlcjsKCXZvaWQgU2VuZFZpYVNvY2tldCgpOwoKCXNhbF9Cb29sIExvYWQoIFN0cmluZyBhRmlsZU5hbWUsIFNiTW9kdWxlICpwTW9kICk7CgoJdm9pZCBSZWFkTmFtZXMoIFN0cmluZyBGaWxlbmFtZSwgQ05hbWVzIComcE5hbWVzLCBDTmFtZXMgKiZwVUlkcywgc2FsX0Jvb2wgYklzRmxhdCA9IHNhbF9GYWxzZSApOwoJdm9pZCBSZWFkRmxhdCggU3RyaW5nIEZpbGVuYW1lLCBDTmFtZXMgKiZwTmFtZXMsIHNhbF9Cb29sIGJTb3J0QnlOYW1lICk7CglzYWxfQm9vbCBSZWFkTmFtZXNCaW4oIFN0cmluZyBGaWxlbmFtZSwgQ05hbWVzIComcFNJZHMsIENOYW1lcyAqJnBDb250cm9scyApOwoJc2FsX0Jvb2wgV3JpdGVOYW1lc0JpbiggU3RyaW5nIEZpbGVuYW1lLCBDTmFtZXMgKnBTSWRzLCBDTmFtZXMgKnBDb250cm9scyApOwogICAgdm9pZCBSZWFkSGlkTHN0QnlOdW1iZXIoKTsKICAgIHZvaWQgU29ydENvbnRyb2xzQnlOdW1iZXIoIHNhbF9Cb29sIGJJbmNsdWRlQWN0aXZlID0gc2FsX0ZhbHNlICk7CgogICAgU3RyaW5nIEdldE1ldGhvZE5hbWUoIHNhbF91TG9uZyBuTWV0aG9kSWQgKTsKICAgIFN0cmluZyBHZXRLZXlOYW1lKCBzYWxfdUludDE2IG5LZXlDb2RlICk7CgoJdm9pZCBXYWl0Rm9yQW5zd2VyICgpOwoJREVDTF9MSU5LKCBJZGxlSGRsLCAgIEFwcGxpY2F0aW9uKiApOwoJREVDTF9MSU5LKCBDYWxsRGlhbG9nSGFuZGxlciwgICBBcHBsaWNhdGlvbiogKTsKCVN0cmluZyBhRGlhbG9nSGFuZGxlck5hbWU7CglzYWxfdUludDE2IG5XaW5kb3dIYW5kbGVyQ2FsbExldmVsOwoKCXNhbF91SW50MTYgbklkbGVDb3VudDsKCS8vIHdlbm4gRGlhbG9nSGFuZGxlciBnZXNldHp0IHdpcmQgZXIgaW0gSWRsZUhhbmRsZXIgaW5rcmVtZW50aWVydCB1bmQKCS8vIGluIFdhaXRGb3JBbnN3ZXIgcvxja2dlc2V0enQuINxiZXJzdGVpZ3QgZXIgZWluZW4gZ2V3aXNzZW4gd2VydCwgZ2VoZSBpY2ggZGF2b24gYXVzLAoJLy8gZGHfIFdhaXRGb3JBbnN3ZXIgc3RpbGwgbGlndCB1bmQgcnVmZSBkaWUgRGlhbG9nSGFuZGVyIFN1YiBpbSBCQVNJQyBhdWYuCgoJdm9pZCBCZWdpbkJsb2NrKCk7Cgl2b2lkIEVuZEJsb2NrKCk7CgoJU2JUZXh0VHlwZSBHZXRTeW1ib2xUeXBlKCBjb25zdCBTdHJpbmcgJnJTeW1ib2wsIHNhbF9Cb29sIGJXYXNDb250cm9sICk7CglzdGF0aWMgQ29udHJvbERlZkxvYWQgY29uc3QgYXJSX0NtZHNbXTsKCXN0YXRpYyBDTmFtZXMgKnBSQ29tbWFuZHM7CgoJc3RhdGljIENFcnJvcnMgKnBGZWhsZXJMaXN0ZTsJCS8vIEhpZXIgd2VyZGVuIGRpZSBGZWhsZXIgZGVzIFRlc3R0b29scyBnZXNwZWljaGVydAoKfTsKCiNlbmRpZgo=