LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8NCg0KI2luY2x1ZGUgInN0ZGFmeC5oIgojaW5jbHVkZSAiVUFjY0NPTTIuaCIKI2luY2x1ZGUgIkVudW1WYXJpYW50LmgiCiNpbmNsdWRlICJNQWNjZXNzaWJsZS5oIgoKI2luY2x1ZGUgImFjdC5oeHgiCgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwovLyBDRW51bVZhcmlhbnQKCgoKLyoqCiAgICogZW51bWFyYXRlIG1ldGhvZCxnZXQgbmV4dCBlbGVtZW50CiAgICogQHBhcmFtICBjRWxlbWVudHMgVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byBiZSByZXR1cm5lZC4gCiAgICogQHBhcmFtICBwdmFyICAgICAgQW4gYXJyYXkgb2YgYXQgbGVhc3Qgc2l6ZSBjZWx0IGluIHdoaWNoIHRoZSBlbGVtZW50cyBhcmUgdG8gYmUgcmV0dXJuZWQuCiAgICogQHBhcmFtICBwY0VsZW1lbnRGZXRjaGVkIFBvaW50ZXIgdG8gdGhlIG51bWJlciBvZiBlbGVtZW50cyByZXR1cm5lZCBpbiByZ1Zhciwgb3IgTnVsbKGjCiAgICogQHJldHVybiBSZXN1bHQuCiAgICovCkhSRVNVTFQgU1RETUVUSE9EQ0FMTFRZUEUgQ0VudW1WYXJpYW50OjpOZXh0KFVMT05HIGNFbGVtZW50cyxWQVJJQU5UIF9fUlBDX0ZBUiAqcHZhcixVTE9ORyBfX1JQQ19GQVIgKnBjRWxlbWVudEZldGNoZWQpCnsKICAgIGxvbmcgbDE7CiAgICBVTE9ORyBsMjsKCiAgICBpZiAocHZhciA9PSBOVUxMKQogICAgICAgIHJldHVybiBFX0lOVkFMSURBUkc7CgoJQ0hFQ0tfRU5BQkxFX0lORgogICAgaWYgKHBjRWxlbWVudEZldGNoZWQgIT0gTlVMTCkKICAgICAgICAqcGNFbGVtZW50RmV0Y2hlZCA9IDA7CgogICAgLy8gUmV0cmlldmUgdGhlIG5leHQgY0VsZW1lbnRzLgogICAgZm9yIChsMT1tX2xDdXJyZW50LCBsMj0wOyBsMTxtX3BYQWNjZXNzaWJsZVNlbGVjdGlvbi0+Z2V0U2VsZWN0ZWRBY2Nlc3NpYmxlQ2hpbGRDb3VudCgpICYmCiAgICAgICAgICAgIGwyPGNFbGVtZW50czsgbDErKywgbDIrKykKICAgIHsKICAgICAgICBSZWZlcmVuY2U8IFhBY2Nlc3NpYmxlID4gcFJYQWNjID0gbV9wWEFjY2Vzc2libGVTZWxlY3Rpb24tPmdldFNlbGVjdGVkQWNjZXNzaWJsZUNoaWxkKGwxKTsKICAgICAgICBJQWNjZXNzaWJsZSogcENoaWxkID0gTlVMTDsKICAgICAgICBCT09MIGlzR2V0ID0gQ01BY2Nlc3NpYmxlOjpnZXRfSUFjY2Vzc2libGVGcm9tWEFjY2Vzc2libGUoKGxvbmcpcFJYQWNjLmdldCgpLCZwQ2hpbGQpOwogICAgICAgIGlmKGlzR2V0KQogICAgICAgIHsKICAgICAgICAgICAgcHZhcltsMl0udnQgPSBWVF9JNDsKICAgICAgICAgICAgKChJTUFjY2Vzc2libGUqKXBDaGlsZCktPkdldF9YQWNjQ2hpbGRJRCgmcHZhcltsMl0ubFZhbCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYocFJYQWNjLmlzKCkpCiAgICAgICAgewogICAgICAgICAgICBpZihDTUFjY2Vzc2libGU6OmdfcEFnZW50KQogICAgICAgICAgICAgICAgQ01BY2Nlc3NpYmxlOjpnX3BBZ2VudC0+SW5zZXJ0QWNjT2JqKHBSWEFjYy5nZXQoKSxwVU5PSW50ZXJmYWNlLE5VTEwpOwogICAgICAgICAgICBCT09MIGlzR2V0ID0gQ01BY2Nlc3NpYmxlOjpnZXRfSUFjY2Vzc2libGVGcm9tWEFjY2Vzc2libGUoKGxvbmcpcFJYQWNjLmdldCgpLCZwQ2hpbGQpOwogICAgICAgICAgICBpZihpc0dldCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcHZhcltsMl0udnQgPSBWVF9JNDsKICAgICAgICAgICAgICAgICgoSU1BY2Nlc3NpYmxlKilwQ2hpbGQpLT5HZXRfWEFjY0NoaWxkSUQoJnB2YXJbbDJdLmxWYWwpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgLy8gU2V0IGNvdW50IG9mIGVsZW1lbnRzIHJldHJpZXZlZC4KICAgIGlmIChwY0VsZW1lbnRGZXRjaGVkICE9IE5VTEwpCiAgICAgICAgKnBjRWxlbWVudEZldGNoZWQgPSBsMjsKICAgIG1fbEN1cnJlbnQgPSBsMTsKCiAgICByZXR1cm4gKGwyIDwgY0VsZW1lbnRzKSA/IFNfRkFMU0UgOiBOT0VSUk9SOwp9CgovKioKICAgKiBza2lwIHRoZSBlbGVtZW50cyBpbiB0aGUgZ2l2ZW4gcmFuZ2Ugd2hlbiBlbnVtYXJhdGUgZWxlbWVudHMKICAgKiBAcGFyYW0gIGNFbGVtZW50cyBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRvIHNraXAuIAogICAqIEByZXR1cm4gUmVzdWx0LgogICAqLwpIUkVTVUxUIFNURE1FVEhPRENBTExUWVBFIENFbnVtVmFyaWFudDo6U2tpcChVTE9ORyBjRWxlbWVudHMpCnsKCUNIRUNLX0VOQUJMRV9JTkYKICAgIG1fbEN1cnJlbnQgKz0gY0VsZW1lbnRzOwogICAgaWYgKG1fbEN1cnJlbnQgPiAobG9uZykobV9sTEJvdW5kK21fcFhBY2Nlc3NpYmxlU2VsZWN0aW9uLT5nZXRTZWxlY3RlZEFjY2Vzc2libGVDaGlsZENvdW50KCkpKQogICAgewogICAgICAgIG1fbEN1cnJlbnQgPSAgbV9sTEJvdW5kK21fcFhBY2Nlc3NpYmxlU2VsZWN0aW9uLT5nZXRTZWxlY3RlZEFjY2Vzc2libGVDaGlsZENvdW50KCk7CiAgICAgICAgcmV0dXJuIEVfRkFJTDsKICAgIH0KICAgIGVsc2UKICAgICAgICByZXR1cm4gTk9FUlJPUjsKfQoKCi8qKgogICAqIHJlc2V0IHRoZSBlbnVtYXJhdGlvbiBwb3NpdGlvbiB0byBpbml0aWFsIHZhbHVlCiAgICogQHBhcmFtIAogICAqIEByZXR1cm4gUmVzdWx0LgogICAqLwpIUkVTVUxUIFNURE1FVEhPRENBTExUWVBFIENFbnVtVmFyaWFudDo6UmVzZXQoIHZvaWQpCnsKICAgIG1fbEN1cnJlbnQgPSBtX2xMQm91bmQ7CiAgICByZXR1cm4gTk9FUlJPUjsKfQoKCi8qKgogICAqY3JlYXRlIGEgbmV3IElFbnVtVmFyaWFudCBvYmplY3QsCiAgICpjb3B5IGN1cnJlbnQgZW51bWFyYXRpb24gY29udGFpbmVyIGFuZCBpdHMgc3RhdGUgdG8gCiAgICp0aGUgbmV3IG9iamVjdAogICAqQVQgd2lsbCB1c2UgdGhlIGNvcHkgb2JqZWN0IHRvIGdldCBlbGVtZW50cwogICAqIEBwYXJhbSBwcGVudW0gT24gcmV0dXJuLCBwb2ludGVyIHRvIHRoZSBsb2NhdGlvbiBvZiB0aGUgY2xvbmUgZW51bWVyYXRvcqGjCiAgICogQHJldHVybiBSZXN1bHQuCiAgICovCkhSRVNVTFQgU1RETUVUSE9EQ0FMTFRZUEUgQ0VudW1WYXJpYW50OjpDbG9uZShJRW51bVZBUklBTlQgX19SUENfRkFSICpfX1JQQ19GQVIgKnBwZW51bSkKewogICAgQ0VudW1WYXJpYW50ICogcGVudW0gPSBOVUxMOwogICAgSFJFU1VMVCBocjsKICAgIGlmIChwcGVudW0gPT0gTlVMTCkKICAgICAgICByZXR1cm4gRV9JTlZBTElEQVJHOwoKICAgICpwcGVudW0gPSBOVUxMOwoKICAgIGhyID0gQ3JlYXRlKCZwZW51bSk7CiAgICBpZiggaHIgPT0gU19PSyApCiAgICB7CiAgICAgICAgcGVudW0tPlB1dFNlbGVjdGlvbigobG9uZylwVU5PSW50ZXJmYWNlKTsKICAgICAgICAqcHBlbnVtID0gcGVudW07CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKHBlbnVtKQogICAgICAgICAgICBwZW51bS0+UmVsZWFzZSgpOwogICAgfQogICAgcmV0dXJuIGhyOwp9CgovKioKICAgKlN0YXRpYyBwdWJsaWMgbWV0aG9kIHRvIGNyZWF0ZSBhIENMU0lEX0VudW1WYXJpYW50IGNvbSBvYmplY3QuCiAgICogQHBhcmFtIHBwZW51bSBQb2ludGVyIHRvIGFjY2VwdCBjb20gb2JqZWN0LgogICAqIEByZXR1cm4gUmVzdWx0LgogICAqLwpIUkVTVUxUIFNURE1FVEhPRENBTExUWVBFIENFbnVtVmFyaWFudDo6Q3JlYXRlKENFbnVtVmFyaWFudCBfX1JQQ19GQVIgKl9fUlBDX0ZBUiAqcHBlbnVtKQp7CglBY3RpdmF0ZUFjdENvbnRleHQoKTsKCUhSRVNVTFQgaHIgPSBDb0NyZWF0ZUluc3RhbmNlKENMU0lEX0VudW1WYXJpYW50LE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENMU0NUWF9TRVJWRVIsSUlEX0lFbnVtVmFyaWFudCwodm9pZCAqKilwcGVudW0pOwoJRGVhY3RpdmF0ZUFjdENvbnRleHQoKTsKCWlmIChTX09LICE9IGhyKQogICAgewogICAgICAgIHJldHVybiBFX0ZBSUw7CiAgICB9CgogICAgcmV0dXJuIFNfT0s7Cn0KCi8qKgogICAqUmV0dXJuIGNvdW50IG9mIGVsZW1lbnRzIGluIGN1cnJlbnQgY29udGFpbmVyCiAgICogQHBhcmFtLgogICAqIEByZXR1cm4gY291bnQgb2YgZWxlbWVudHMgaW4gY3VycmVudCBjb250YWluZXIuCiAgICovCmxvbmcgQ0VudW1WYXJpYW50OjpHZXRDb3VudE9mRWxlbWVudHMoKQp7CglDSEVDS19FTkFCTEVfSU5GX1pFUk8KCiAgICBpZihtX3BYQWNjZXNzaWJsZVNlbGVjdGlvbi5pcygpKQogICAgICAgIHJldHVybiBtX3BYQWNjZXNzaWJsZVNlbGVjdGlvbi0+Z2V0U2VsZWN0ZWRBY2Nlc3NpYmxlQ2hpbGRDb3VudCgpOwogICAgcmV0dXJuIDA7Cn0KCi8qKgogICAqIFNldCBtZW1lYmVyIG1fcFhBY2Nlc3NpYmxlU2VsZWN0aW9uIHRvIE5VTEwgYW5kIG1fbEN1cnJlbnQgdG8gbV9sTEJvdW5kLgogICAqIEBwYXJhbS4KICAgKiBAcmV0dXJuIFJlc3VsdAogICAqLwpTVERNRVRIT0RJTVAgQ0VudW1WYXJpYW50OjpDbGVhckVudW1lcmF0aW9uKCkKewogICAgcFVOT0ludGVyZmFjZSA9IE5VTEw7CiAgICBtX3BYQWNjZXNzaWJsZVNlbGVjdGlvbiA9IE5VTEw7CiAgICBtX2xDdXJyZW50ID0gbV9sTEJvdW5kOwogICAgcmV0dXJuIFNfT0s7Cn0KCi8qKgogICAqU3RhdGljIG1ldGhvZCB0byBmZXRjaCBYQWNjZXNzaWJsZVNlbGVjdGlvbgogICAqIEBwYXJhbSBwWEFjYyBYQWNjZXNzaWJsZSBpbnRlcmZhY2UuCiAgICogQHJldHVybiBYQWNjZXNzaWJsZVNlbGVjdGlvbiBpbnRlcmZhY2UuCiAgICovCnN0YXRpYyBSZWZlcmVuY2U8WEFjY2Vzc2libGVTZWxlY3Rpb24+IEdldFhBY2Nlc3NpYmxlU2VsZWN0aW9uKFhBY2Nlc3NpYmxlKiBwWEFjYykKewogICAgWEFjY2Vzc2libGVTZWxlY3Rpb24qIHBTZWxlY3Rpb24gPSBOVUxMOwogICAgUmVmZXJlbmNlPCBYQWNjZXNzaWJsZUNvbnRleHQgPiBwUkNvbnRleHQ7CgogICAgaWYoIHBYQWNjID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgcFJDb250ZXh0ID0gcFhBY2MtPmdldEFjY2Vzc2libGVDb250ZXh0KCk7CiAgICBpZiggIXBSQ29udGV4dC5pcygpICkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBSZWZlcmVuY2U8IFhBY2Nlc3NpYmxlU2VsZWN0aW9uID4gcFJTZWxlY3Rpb24ocFJDb250ZXh0LFVOT19RVUVSWSk7CiAgICBpZiggIXBSU2VsZWN0aW9uLmlzKCkgKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIHJldHVybiBwUlNlbGVjdGlvbjsKfQoKLyoqCiAgICogUHV0IHZhbGlkIFVOTyBYQWNjZXNzaWJsZSBpbnRlcmZhY2UuCiAgICogQHBhcmFtIHBYU2VsZWN0aW9uIFhBY2Nlc3NpYmxlIGludGVyZmFjZS4KICAgKiBAcmV0dXJuIFJlc3VsdC4uCiAgICovClNURE1FVEhPRElNUCBDRW51bVZhcmlhbnQ6OlB1dFNlbGVjdGlvbihsb25nIHBYU2VsZWN0aW9uKQp7CiAgICBwVU5PSW50ZXJmYWNlID0gKFhBY2Nlc3NpYmxlKilwWFNlbGVjdGlvbjsKICAgIG1fcFhBY2Nlc3NpYmxlU2VsZWN0aW9uID0gR2V0WEFjY2Vzc2libGVTZWxlY3Rpb24ocFVOT0ludGVyZmFjZSk7CiAgICByZXR1cm4gU19PSzsKfQo=