LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQogKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgInN0ZGFmeC5oIgojaW5jbHVkZSAiVUFjY0NPTTIuaCIKI2luY2x1ZGUgIkVudW1WYXJpYW50LmgiCiNpbmNsdWRlICJNQWNjZXNzaWJsZS5oIgoKI2luY2x1ZGUgImFjdC5oeHgiCgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwovLyBDRW51bVZhcmlhbnQKCgoKLyoqCiAgICogZW51bWFyYXRlIG1ldGhvZCxnZXQgbmV4dCBlbGVtZW50CiAgICogQHBhcmFtICBjRWxlbWVudHMgVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byBiZSByZXR1cm5lZC4KICAgKiBAcGFyYW0gIHB2YXIgICAgICBBbiBhcnJheSBvZiBhdCBsZWFzdCBzaXplIGNlbHQgaW4gd2hpY2ggdGhlIGVsZW1lbnRzIGFyZSB0byBiZSByZXR1cm5lZC4KICAgKiBAcGFyYW0gIHBjRWxlbWVudEZldGNoZWQgUG9pbnRlciB0byB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIHJldHVybmVkIGluIHJnVmFyLCBvciBOdWxsoaMKICAgKiBAcmV0dXJuIFJlc3VsdC4KICAgKi8KSFJFU1VMVCBTVERNRVRIT0RDQUxMVFlQRSBDRW51bVZhcmlhbnQ6Ok5leHQoVUxPTkcgY0VsZW1lbnRzLFZBUklBTlQgX19SUENfRkFSICpwdmFyLFVMT05HIF9fUlBDX0ZBUiAqcGNFbGVtZW50RmV0Y2hlZCkKewogICAgbG9uZyBsMTsKICAgIFVMT05HIGwyOwoKICAgIGlmIChwdmFyID09IE5VTEwpCiAgICAgICAgcmV0dXJuIEVfSU5WQUxJREFSRzsKCglDSEVDS19FTkFCTEVfSU5GCiAgICBpZiAocGNFbGVtZW50RmV0Y2hlZCAhPSBOVUxMKQogICAgICAgICpwY0VsZW1lbnRGZXRjaGVkID0gMDsKCiAgICAvLyBSZXRyaWV2ZSB0aGUgbmV4dCBjRWxlbWVudHMuCiAgICBmb3IgKGwxPW1fbEN1cnJlbnQsIGwyPTA7IGwxPG1fcFhBY2Nlc3NpYmxlU2VsZWN0aW9uLT5nZXRTZWxlY3RlZEFjY2Vzc2libGVDaGlsZENvdW50KCkgJiYKICAgICAgICAgICAgbDI8Y0VsZW1lbnRzOyBsMSsrLCBsMisrKQogICAgewogICAgICAgIFJlZmVyZW5jZTwgWEFjY2Vzc2libGUgPiBwUlhBY2MgPSBtX3BYQWNjZXNzaWJsZVNlbGVjdGlvbi0+Z2V0U2VsZWN0ZWRBY2Nlc3NpYmxlQ2hpbGQobDEpOwogICAgICAgIElBY2Nlc3NpYmxlKiBwQ2hpbGQgPSBOVUxMOwogICAgICAgIEJPT0wgaXNHZXQgPSBDTUFjY2Vzc2libGU6OmdldF9JQWNjZXNzaWJsZUZyb21YQWNjZXNzaWJsZSgobG9uZylwUlhBY2MuZ2V0KCksJnBDaGlsZCk7CiAgICAgICAgaWYoaXNHZXQpCiAgICAgICAgewogICAgICAgICAgICBwdmFyW2wyXS52dCA9IFZUX0k0OwogICAgICAgICAgICAoKElNQWNjZXNzaWJsZSopcENoaWxkKS0+R2V0X1hBY2NDaGlsZElEKCZwdmFyW2wyXS5sVmFsKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZihwUlhBY2MuaXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIGlmKENNQWNjZXNzaWJsZTo6Z19wQWdlbnQpCiAgICAgICAgICAgICAgICBDTUFjY2Vzc2libGU6OmdfcEFnZW50LT5JbnNlcnRBY2NPYmoocFJYQWNjLmdldCgpLHBVTk9JbnRlcmZhY2UsTlVMTCk7CiAgICAgICAgICAgIEJPT0wgaXNHZXQgPSBDTUFjY2Vzc2libGU6OmdldF9JQWNjZXNzaWJsZUZyb21YQWNjZXNzaWJsZSgobG9uZylwUlhBY2MuZ2V0KCksJnBDaGlsZCk7CiAgICAgICAgICAgIGlmKGlzR2V0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwdmFyW2wyXS52dCA9IFZUX0k0OwogICAgICAgICAgICAgICAgKChJTUFjY2Vzc2libGUqKXBDaGlsZCktPkdldF9YQWNjQ2hpbGRJRCgmcHZhcltsMl0ubFZhbCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAvLyBTZXQgY291bnQgb2YgZWxlbWVudHMgcmV0cmlldmVkLgogICAgaWYgKHBjRWxlbWVudEZldGNoZWQgIT0gTlVMTCkKICAgICAgICAqcGNFbGVtZW50RmV0Y2hlZCA9IGwyOwogICAgbV9sQ3VycmVudCA9IGwxOwoKICAgIHJldHVybiAobDIgPCBjRWxlbWVudHMpID8gU19GQUxTRSA6IE5PRVJST1I7Cn0KCi8qKgogICAqIHNraXAgdGhlIGVsZW1lbnRzIGluIHRoZSBnaXZlbiByYW5nZSB3aGVuIGVudW1hcmF0ZSBlbGVtZW50cwogICAqIEBwYXJhbSAgY0VsZW1lbnRzIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgdG8gc2tpcC4KICAgKiBAcmV0dXJuIFJlc3VsdC4KICAgKi8KSFJFU1VMVCBTVERNRVRIT0RDQUxMVFlQRSBDRW51bVZhcmlhbnQ6OlNraXAoVUxPTkcgY0VsZW1lbnRzKQp7CglDSEVDS19FTkFCTEVfSU5GCiAgICBtX2xDdXJyZW50ICs9IGNFbGVtZW50czsKICAgIGlmIChtX2xDdXJyZW50ID4gKGxvbmcpKG1fbExCb3VuZCttX3BYQWNjZXNzaWJsZVNlbGVjdGlvbi0+Z2V0U2VsZWN0ZWRBY2Nlc3NpYmxlQ2hpbGRDb3VudCgpKSkKICAgIHsKICAgICAgICBtX2xDdXJyZW50ID0gIG1fbExCb3VuZCttX3BYQWNjZXNzaWJsZVNlbGVjdGlvbi0+Z2V0U2VsZWN0ZWRBY2Nlc3NpYmxlQ2hpbGRDb3VudCgpOwogICAgICAgIHJldHVybiBFX0ZBSUw7CiAgICB9CiAgICBlbHNlCiAgICAgICAgcmV0dXJuIE5PRVJST1I7Cn0KCgovKioKICAgKiByZXNldCB0aGUgZW51bWFyYXRpb24gcG9zaXRpb24gdG8gaW5pdGlhbCB2YWx1ZQogICAqIEBwYXJhbQogICAqIEByZXR1cm4gUmVzdWx0LgogICAqLwpIUkVTVUxUIFNURE1FVEhPRENBTExUWVBFIENFbnVtVmFyaWFudDo6UmVzZXQoIHZvaWQpCnsKICAgIG1fbEN1cnJlbnQgPSBtX2xMQm91bmQ7CiAgICByZXR1cm4gTk9FUlJPUjsKfQoKCi8qKgogICAqY3JlYXRlIGEgbmV3IElFbnVtVmFyaWFudCBvYmplY3QsCiAgICpjb3B5IGN1cnJlbnQgZW51bWFyYXRpb24gY29udGFpbmVyIGFuZCBpdHMgc3RhdGUgdG8KICAgKnRoZSBuZXcgb2JqZWN0CiAgICpBVCB3aWxsIHVzZSB0aGUgY29weSBvYmplY3QgdG8gZ2V0IGVsZW1lbnRzCiAgICogQHBhcmFtIHBwZW51bSBPbiByZXR1cm4sIHBvaW50ZXIgdG8gdGhlIGxvY2F0aW9uIG9mIHRoZSBjbG9uZSBlbnVtZXJhdG9yoaMKICAgKiBAcmV0dXJuIFJlc3VsdC4KICAgKi8KSFJFU1VMVCBTVERNRVRIT0RDQUxMVFlQRSBDRW51bVZhcmlhbnQ6OkNsb25lKElFbnVtVkFSSUFOVCBfX1JQQ19GQVIgKl9fUlBDX0ZBUiAqcHBlbnVtKQp7CiAgICBDRW51bVZhcmlhbnQgKiBwZW51bSA9IE5VTEw7CiAgICBIUkVTVUxUIGhyOwogICAgaWYgKHBwZW51bSA9PSBOVUxMKQogICAgICAgIHJldHVybiBFX0lOVkFMSURBUkc7CgogICAgKnBwZW51bSA9IE5VTEw7CgogICAgaHIgPSBDcmVhdGUoJnBlbnVtKTsKICAgIGlmKCBociA9PSBTX09LICkKICAgIHsKICAgICAgICBwZW51bS0+UHV0U2VsZWN0aW9uKChsb25nKXBVTk9JbnRlcmZhY2UpOwogICAgICAgICpwcGVudW0gPSBwZW51bTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpZiAocGVudW0pCiAgICAgICAgICAgIHBlbnVtLT5SZWxlYXNlKCk7CiAgICB9CiAgICByZXR1cm4gaHI7Cn0KCi8qKgogICAqU3RhdGljIHB1YmxpYyBtZXRob2QgdG8gY3JlYXRlIGEgQ0xTSURfRW51bVZhcmlhbnQgY29tIG9iamVjdC4KICAgKiBAcGFyYW0gcHBlbnVtIFBvaW50ZXIgdG8gYWNjZXB0IGNvbSBvYmplY3QuCiAgICogQHJldHVybiBSZXN1bHQuCiAgICovCkhSRVNVTFQgU1RETUVUSE9EQ0FMTFRZUEUgQ0VudW1WYXJpYW50OjpDcmVhdGUoQ0VudW1WYXJpYW50IF9fUlBDX0ZBUiAqX19SUENfRkFSICpwcGVudW0pCnsKCUFjdGl2YXRlQWN0Q29udGV4dCgpOwoJSFJFU1VMVCBociA9IENvQ3JlYXRlSW5zdGFuY2UoQ0xTSURfRW51bVZhcmlhbnQsTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0xTQ1RYX1NFUlZFUixJSURfSUVudW1WYXJpYW50LCh2b2lkICoqKXBwZW51bSk7CglEZWFjdGl2YXRlQWN0Q29udGV4dCgpOwoJaWYgKFNfT0sgIT0gaHIpCiAgICB7CiAgICAgICAgcmV0dXJuIEVfRkFJTDsKICAgIH0KCiAgICByZXR1cm4gU19PSzsKfQoKLyoqCiAgICpSZXR1cm4gY291bnQgb2YgZWxlbWVudHMgaW4gY3VycmVudCBjb250YWluZXIKICAgKiBAcGFyYW0uCiAgICogQHJldHVybiBjb3VudCBvZiBlbGVtZW50cyBpbiBjdXJyZW50IGNvbnRhaW5lci4KICAgKi8KbG9uZyBDRW51bVZhcmlhbnQ6OkdldENvdW50T2ZFbGVtZW50cygpCnsKCUNIRUNLX0VOQUJMRV9JTkZfWkVSTwoKICAgIGlmKG1fcFhBY2Nlc3NpYmxlU2VsZWN0aW9uLmlzKCkpCiAgICAgICAgcmV0dXJuIG1fcFhBY2Nlc3NpYmxlU2VsZWN0aW9uLT5nZXRTZWxlY3RlZEFjY2Vzc2libGVDaGlsZENvdW50KCk7CiAgICByZXR1cm4gMDsKfQoKLyoqCiAgICogU2V0IG1lbWJlciBtX3BYQWNjZXNzaWJsZVNlbGVjdGlvbiB0byBOVUxMIGFuZCBtX2xDdXJyZW50IHRvIG1fbExCb3VuZC4KICAgKiBAcGFyYW0uCiAgICogQHJldHVybiBSZXN1bHQKICAgKi8KU1RETUVUSE9ESU1QIENFbnVtVmFyaWFudDo6Q2xlYXJFbnVtZXJhdGlvbigpCnsKICAgIHBVTk9JbnRlcmZhY2UgPSBOVUxMOwogICAgbV9wWEFjY2Vzc2libGVTZWxlY3Rpb24gPSBOVUxMOwogICAgbV9sQ3VycmVudCA9IG1fbExCb3VuZDsKICAgIHJldHVybiBTX09LOwp9CgovKioKICAgKlN0YXRpYyBtZXRob2QgdG8gZmV0Y2ggWEFjY2Vzc2libGVTZWxlY3Rpb24KICAgKiBAcGFyYW0gcFhBY2MgWEFjY2Vzc2libGUgaW50ZXJmYWNlLgogICAqIEByZXR1cm4gWEFjY2Vzc2libGVTZWxlY3Rpb24gaW50ZXJmYWNlLgogICAqLwpzdGF0aWMgUmVmZXJlbmNlPFhBY2Nlc3NpYmxlU2VsZWN0aW9uPiBHZXRYQWNjZXNzaWJsZVNlbGVjdGlvbihYQWNjZXNzaWJsZSogcFhBY2MpCnsKICAgIFhBY2Nlc3NpYmxlU2VsZWN0aW9uKiBwU2VsZWN0aW9uID0gTlVMTDsKICAgIFJlZmVyZW5jZTwgWEFjY2Vzc2libGVDb250ZXh0ID4gcFJDb250ZXh0OwoKICAgIGlmKCBwWEFjYyA9PSBOVUxMKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIHBSQ29udGV4dCA9IHBYQWNjLT5nZXRBY2Nlc3NpYmxlQ29udGV4dCgpOwogICAgaWYoICFwUkNvbnRleHQuaXMoKSApCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgUmVmZXJlbmNlPCBYQWNjZXNzaWJsZVNlbGVjdGlvbiA+IHBSU2VsZWN0aW9uKHBSQ29udGV4dCxVTk9fUVVFUlkpOwogICAgaWYoICFwUlNlbGVjdGlvbi5pcygpICkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICByZXR1cm4gcFJTZWxlY3Rpb247Cn0KCi8qKgogICAqIFB1dCB2YWxpZCBVTk8gWEFjY2Vzc2libGUgaW50ZXJmYWNlLgogICAqIEBwYXJhbSBwWFNlbGVjdGlvbiBYQWNjZXNzaWJsZSBpbnRlcmZhY2UuCiAgICogQHJldHVybiBSZXN1bHQuLgogICAqLwpTVERNRVRIT0RJTVAgQ0VudW1WYXJpYW50OjpQdXRTZWxlY3Rpb24obG9uZyBwWFNlbGVjdGlvbikKewogICAgcFVOT0ludGVyZmFjZSA9IChYQWNjZXNzaWJsZSopcFhTZWxlY3Rpb247CiAgICBtX3BYQWNjZXNzaWJsZVNlbGVjdGlvbiA9IEdldFhBY2Nlc3NpYmxlU2VsZWN0aW9uKHBVTk9JbnRlcmZhY2UpOwogICAgcmV0dXJuIFNfT0s7Cn0K