LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgICAKICogRmlsZW5hbWU6ICAgICAgYWN0aXN5cy5jCiAqIFZlcnNpb246ICAgICAgIDEuMQogKiBEZXNjcmlwdGlvbjogICBJbXBsZW1lbnRhdGlvbiBmb3IgdGhlIEFDVGlTWVMgSVItMjIwTCBhbmQgSVItMjIwTCsgCiAqICAgICAgICAgICAgICAgIGRvbmdsZXMKICogU3RhdHVzOiAgICAgICAgQmV0YS4KICogQXV0aG9yczogICAgICAgRGFnIEJyYXR0bGkgPGRhZ2JAY3MudWl0Lm5vPiAoaW5pdGlhbGx5KQogKgkJICBKZWFuIFRvdXJyaWxoZXMgPGp0QGhwbC5ocC5jb20+IChuZXcgdmVyc2lvbikKICoJCSAgTWFydGluIERpZWhsIDxtYWRAbWRpZWhsLmRlPiAobmV3IHZlcnNpb24gZm9yIHNpcl9kZXYpCiAqIENyZWF0ZWQgYXQ6ICAgIFdlZCBPY3QgMjEgMjA6MDI6MzUgMTk5OAogKiBNb2RpZmllZCBhdDogICBTdW4gT2N0IDI3IDIyOjAyOjEzIDIwMDIKICogTW9kaWZpZWQgYnk6ICAgTWFydGluIERpZWhsIDxtYWRAbWRpZWhsLmRlPgogKiAKICogICAgIENvcHlyaWdodCAoYykgMTk5OC0xOTk5IERhZyBCcmF0dGxpLCBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiAgICAgQ29weXJpZ2h0IChjKSAxOTk5IEplYW4gVG91cnJpbGhlcwogKiAgICAgQ29weXJpZ2h0IChjKSAyMDAyIE1hcnRpbiBEaWVobAogKiAgICAgIAogKiAgICAgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciAKICogICAgIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIAogKiAgICAgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgCiAqICAgICB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICogIAogKiAgICAgTmVpdGhlciBEYWcgQnJhdHRsaSBub3IgVW5pdmVyc2l0eSBvZiBUcm9tc/ggYWRtaXQgbGlhYmlsaXR5IG5vcgogKiAgICAgcHJvdmlkZSB3YXJyYW50eSBmb3IgYW55IG9mIHRoaXMgc29mdHdhcmUuIFRoaXMgbWF0ZXJpYWwgaXMgCiAqICAgICBwcm92aWRlZCAiQVMtSVMiIGFuZCBhdCBubyBjaGFyZ2UuCiAqICAgICAKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoKICogQ2hhbmdlbG9nCiAqCiAqIDAuOCAtPiAwLjk5OTkgLSBKZWFuCiAqCW8gTmV3IGluaXRpYWxpc2F0aW9uIHByb2NlZHVyZSA6IG11Y2ggc2FmZXIgYW5kIGNvcnJlY3QKICoJbyBOZXcgcHJvY2VkdXJlIHRoZSBjaGFuZ2Ugc3BlZWQgOiBtdWNoIGZhc3RlciBhbmQgc2ltcGxlcgogKglvIE90aGVyIGNsZWFudXBzICYgY29tbWVudHMKICoJVGhhbmtzIHRvIExpY2hlbiBXYW5nIEAgQWN0aXN5cyBmb3IgaGlzIGV4Y2VsbGVudCBoZWxwLi4uCiAqCiAqIDEuMCAtPiAxLjEgLSBNYXJ0aW4gRGllaGwKICoJbW9kaWZpZWQgZm9yIG5ldyBzaXIgaW5mcmFzdHJ1Y3R1cmUKICovCgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgoKI2luY2x1ZGUgPG5ldC9pcmRhL2lyZGEuaD4KCiNpbmNsdWRlICJzaXItZGV2LmgiCgovKiAKICogRGVmaW5lIHRoZSB0aW1pbmcgb2YgdGhlIHB1bHNlcyB3ZSBzZW5kIHRvIHRoZSBkb25nbGUgKHRvIHJlc2V0IGl0LCBhbmQKICogdG8gdG9nZ2xlIHNwZWVkcykuIEJhc2ljYWxseSwgdGhlIGxpbWl0IGhlcmUgaXMgdGhlIHByb3BhZ2F0aW9uIHNwZWVkIG9mCiAqIHRoZSBzaWduYWxzIHRocm91Z2ggdGhlIHNlcmlhbCBwb3J0LCB0aGUgZG9uZ2xlIGJlaW5nIG11Y2ggZmFzdGVyLiAgQW55CiAqIHNlcmlhbCBwb3J0IHN1cHBvcnQgMTE1IGtiL3MsIHNvIHdlIGFyZSBzdXJlIHRoYXQgcHVsc2VzIDguNSB1cyB3aWRlIGNhbgogKiBnbyB0aHJvdWdoIGNsZWFubHkgLiBJZiB5b3UgYXJlIG9uIHRoZSB3aWxkIHNpZGUsIHlvdSBjYW4gdHJ5IHRvIGxvd2VyCiAqIHRoaXMgdmFsdWUgKEFjdGlzeXMgcmVjb21tZW5kZWQgbWUgMiB1cywgYW5kIDAgdXMgd29yayBmb3IgbWUgb24gYSBQMjMzISkKICovCiNkZWZpbmUgTUlOX0RFTEFZIDEwCS8qIDEwIHVzIHRvIGJlIG9uIHRoZSBjb25zZXJ2YXRpdmUgc2lkZSAqLwoKc3RhdGljIGludCBhY3Rpc3lzX29wZW4oc3RydWN0IHNpcl9kZXYgKik7CnN0YXRpYyBpbnQgYWN0aXN5c19jbG9zZShzdHJ1Y3Qgc2lyX2RldiAqKTsKc3RhdGljIGludCBhY3Rpc3lzX2NoYW5nZV9zcGVlZChzdHJ1Y3Qgc2lyX2RldiAqLCB1bnNpZ25lZCk7CnN0YXRpYyBpbnQgYWN0aXN5c19yZXNldChzdHJ1Y3Qgc2lyX2RldiAqKTsKCi8qIFRoZXNlIGFyZSB0aGUgYmF1ZHJhdGVzIHN1cHBvcnRlZCwgaW4gdGhlIG9yZGVyIGF2YWlsYWJsZSAqLwovKiBOb3RlIDogdGhlIDIyMEwgZG9lc24ndCBzdXBwb3J0IDM4NDAwLCBidXQgd2Ugd2lsbCBmaXggdGhhdCBiZWxvdyAqLwpzdGF0aWMgdW5zaWduZWQgYmF1ZF9yYXRlc1tdID0geyA5NjAwLCAxOTIwMCwgNTc2MDAsIDExNTIwMCwgMzg0MDAgfTsKCiNkZWZpbmUgTUFYX1NQRUVEUyBBUlJBWV9TSVpFKGJhdWRfcmF0ZXMpCgpzdGF0aWMgc3RydWN0IGRvbmdsZV9kcml2ZXIgYWN0MjIwbCA9IHsKCS5vd25lcgkJPSBUSElTX01PRFVMRSwKCS5kcml2ZXJfbmFtZQk9ICJBY3Rpc3lzIEFDVC0yMjBMIiwKCS50eXBlCQk9IElSREFfQUNUSVNZU19ET05HTEUsCgkub3BlbgkJPSBhY3Rpc3lzX29wZW4sCgkuY2xvc2UJCT0gYWN0aXN5c19jbG9zZSwKCS5yZXNldAkJPSBhY3Rpc3lzX3Jlc2V0LAoJLnNldF9zcGVlZAk9IGFjdGlzeXNfY2hhbmdlX3NwZWVkLAp9OwoKc3RhdGljIHN0cnVjdCBkb25nbGVfZHJpdmVyIGFjdDIyMGxfcGx1cyA9IHsKCS5vd25lcgkJPSBUSElTX01PRFVMRSwKCS5kcml2ZXJfbmFtZQk9ICJBY3Rpc3lzIEFDVC0yMjBMKyIsCgkudHlwZQkJPSBJUkRBX0FDVElTWVNfUExVU19ET05HTEUsCgkub3BlbgkJPSBhY3Rpc3lzX29wZW4sCgkuY2xvc2UJCT0gYWN0aXN5c19jbG9zZSwKCS5yZXNldAkJPSBhY3Rpc3lzX3Jlc2V0LAoJLnNldF9zcGVlZAk9IGFjdGlzeXNfY2hhbmdlX3NwZWVkLAp9OwoKc3RhdGljIGludCBfX2luaXQgYWN0aXN5c19zaXJfaW5pdCh2b2lkKQp7CglpbnQgcmV0OwoKCS8qIEZpcnN0LCByZWdpc3RlciBhbiBBY3Rpc3lzIDIyMEwgZG9uZ2xlICovCglyZXQgPSBpcmRhX3JlZ2lzdGVyX2RvbmdsZSgmYWN0MjIwbCk7CglpZiAocmV0IDwgMCkKCQlyZXR1cm4gcmV0OwoKCS8qIE5vdywgcmVnaXN0ZXIgYW4gQWN0aXN5cyAyMjBMKyBkb25nbGUgKi8KCXJldCA9IGlyZGFfcmVnaXN0ZXJfZG9uZ2xlKCZhY3QyMjBsX3BsdXMpOwoJaWYgKHJldCA8IDApIHsKCQlpcmRhX3VucmVnaXN0ZXJfZG9uZ2xlKCZhY3QyMjBsKTsKCQlyZXR1cm4gcmV0OwoJfQoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBhY3Rpc3lzX3Npcl9jbGVhbnVwKHZvaWQpCnsKCS8qIFdlIGhhdmUgdG8gcmVtb3ZlIGJvdGggZG9uZ2xlcyAqLwoJaXJkYV91bnJlZ2lzdGVyX2RvbmdsZSgmYWN0MjIwbF9wbHVzKTsKCWlyZGFfdW5yZWdpc3Rlcl9kb25nbGUoJmFjdDIyMGwpOwp9CgpzdGF0aWMgaW50IGFjdGlzeXNfb3BlbihzdHJ1Y3Qgc2lyX2RldiAqZGV2KQp7CglzdHJ1Y3QgcW9zX2luZm8gKnFvcyA9ICZkZXYtPnFvczsKCglzaXJkZXZfc2V0X2R0cl9ydHMoZGV2LCBUUlVFLCBUUlVFKTsKCgkvKiBTZXQgdGhlIHNwZWVkcyB3ZSBjYW4gYWNjZXB0ICovCglxb3MtPmJhdWRfcmF0ZS5iaXRzICY9IElSXzk2MDB8SVJfMTkyMDB8SVJfMzg0MDB8SVJfNTc2MDB8SVJfMTE1MjAwOwoKCS8qIFJlbW92ZSBzdXBwb3J0IGZvciAzODQwMCBpZiB0aGlzIGlzIG5vdCBhIDIyMEwrIGRvbmdsZSAqLwoJaWYgKGRldi0+ZG9uZ2xlX2Rydi0+dHlwZSA9PSBJUkRBX0FDVElTWVNfRE9OR0xFKQoJCXFvcy0+YmF1ZF9yYXRlLmJpdHMgJj0gfklSXzM4NDAwOwoKCXFvcy0+bWluX3R1cm5fdGltZS5iaXRzID0gMHg3ZjsgLyogTmVlZHMgMC4wMSBtcyAqLwoJaXJkYV9xb3NfYml0c190b192YWx1ZShxb3MpOwoKCS8qIGlyZGEgdGhyZWFkIHdhaXRzIDUwIG1zZWMgZm9yIHBvd2VyIHNldHRsaW5nICovCgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgYWN0aXN5c19jbG9zZShzdHJ1Y3Qgc2lyX2RldiAqZGV2KQp7CgkvKiBQb3dlciBvZmYgdGhlIGRvbmdsZSAqLwoJc2lyZGV2X3NldF9kdHJfcnRzKGRldiwgRkFMU0UsIEZBTFNFKTsKCglyZXR1cm4gMDsKfQoKLyoKICogRnVuY3Rpb24gYWN0aXN5c19jaGFuZ2Vfc3BlZWQgKHRhc2spCiAqCiAqICAgIENoYW5nZSBzcGVlZCBvZiB0aGUgQUNUaVNZUyBJUi0yMjBMIGFuZCBJUi0yMjBMKyB0eXBlIElyREEgZG9uZ2xlcy4KICogICAgVG8gY3ljbGUgdGhyb3VnaCB0aGUgYXZhaWxhYmxlIGJhdWQgcmF0ZXMsIHB1bHNlIFJUUyBsb3cgZm9yIGEgZmV3IHVzLgogKgogKglGaXJzdCwgd2UgcmVzZXQgdGhlIGRvbmdsZSB0byBhbHdheXMgc3RhcnQgZnJvbSBhIGtub3duIHN0YXRlLgogKglUaGVuLCB3ZSBjeWNsZSB0aHJvdWdoIHRoZSBzcGVlZHMgYnkgcHVsc2luZyBSVFMgbG93IGFuZCB0aGVuIHVwLgogKglUaGUgZG9uZ2xlIGFsbG93IHVzIHRvIHB1bHNlIHF1aXRlIGZhc3QsIHNlIHdlIGNhbiBzZXQgc3BlZWQgaW4gb25lIGdvLAogKiB3aGljaCBpcyBtdXN0IGZhc3RlciAoIDwgMTAwIHVzKSBhbmQgbGVzcyBjb21wbGV4IHRoYW4gd2hhdCBpcyBmb3VuZAogKiBpbiBzb21lIG90aGVyIGRvbmdsZSBkcml2ZXJzLi4uCiAqCU5vdGUgdGhhdCBldmVuIGlmIHRoZSBuZXcgc3BlZWQgaXMgdGhlIHNhbWUgYXMgdGhlIGN1cnJlbnQgc3BlZWQsCiAqIHdlIHJlYXNzZXJ0IHRoZSBzcGVlZC4gVGhpcyBtYWtlIHN1cmUgdGhhdCB0aGluZ3MgYXJlIGFsbCByaWdodCwKICogYW5kIGl0J3MgZmFzdCBhbnl3YXkuLi4KICoJQnkgdGhlIHdheSwgdGhpcyBmdW5jdGlvbiB3aWxsIHdvcmsgZm9yIGJvdGggdHlwZSBvZiBkb25nbGVzLAogKiBiZWNhdXNlIHRoZSBhZGRpdGlvbmFsIHNwZWVkIGlzIGF0IHRoZSBlbmQgb2YgdGhlIHNlcXVlbmNlLi4uCiAqLwpzdGF0aWMgaW50IGFjdGlzeXNfY2hhbmdlX3NwZWVkKHN0cnVjdCBzaXJfZGV2ICpkZXYsIHVuc2lnbmVkIHNwZWVkKQp7CglpbnQgcmV0ID0gMDsKCWludCBpID0gMDsKCiAgICAgICAgSVJEQV9ERUJVRyg0LCAiJXMoKSwgc3BlZWQ9JWQgKHdhcyAlZClcbiIsIF9fRlVOQ1RJT05fXywKICAgICAgICAJc3BlZWQsIGRldi0+c3BlZWQpOwoKCS8qIGRvbmdsZSB3YXMgYWxyZWFkeSByZXNldHRlZCBmcm9tIGlyZGFfcmVxdWVzdCBzdGF0ZSBtYWNoaW5lLAoJICogd2UgYXJlIGluIGtub3duIHN0YXRlIChkb25nbGUgZGVmYXVsdCkKCSAqLwoKCS8qIAoJICogTm93LCB3ZSBjYW4gc2V0IHRoZSBzcGVlZCByZXF1ZXN0ZWQuIFNlbmQgUlRTIHB1bHNlcyB1bnRpbCB3ZQogICAgICAgICAqIHJlYWNoIHRoZSB0YXJnZXQgc3BlZWQgCgkgKi8KCWZvciAoaSA9IDA7IGkgPCBNQVhfU1BFRURTOyBpKyspIHsKCQlpZiAoc3BlZWQgPT0gYmF1ZF9yYXRlc1tpXSkgewoJCQlkZXYtPnNwZWVkID0gc3BlZWQ7CgkJCWJyZWFrOwoJCX0KCQkvKiBTZXQgUlRTIGxvdyBmb3IgMTAgdXMgKi8KCQlzaXJkZXZfc2V0X2R0cl9ydHMoZGV2LCBUUlVFLCBGQUxTRSk7CgkJdWRlbGF5KE1JTl9ERUxBWSk7CgoJCS8qIFNldCBSVFMgaGlnaCBmb3IgMTAgdXMgKi8KCQlzaXJkZXZfc2V0X2R0cl9ydHMoZGV2LCBUUlVFLCBUUlVFKTsKCQl1ZGVsYXkoTUlOX0RFTEFZKTsKCX0KCgkvKiBDaGVjayBpZiBsaWZlIGlzIHN3ZWV0Li4uICovCglpZiAoaSA+PSBNQVhfU1BFRURTKSB7CgkJYWN0aXN5c19yZXNldChkZXYpOwoJCXJldCA9IC1FSU5WQUw7ICAvKiBUaGlzIHNob3VsZCBub3QgaGFwcGVuICovCgl9CgoJLyogQmFzdGEgbGF2b3JvLCBvbiBzZSBjYXNzZSBkJ2ljaS4uLiAqLwoJcmV0dXJuIHJldDsKfQoKLyoKICogRnVuY3Rpb24gYWN0aXN5c19yZXNldCAodGFzaykKICoKICogICAgICBSZXNldCB0aGUgQWN0aXN5cyB0eXBlIGRvbmdsZS4gV2FybmluZywgdGhpcyBmdW5jdGlvbiBtdXN0IG9ubHkgYmUKICogICAgICBjYWxsZWQgd2l0aCBhIHByb2Nlc3MgY29udGV4dCEKICoKICogV2UgbmVlZCB0byBkbyB0d28gdGhpbmdzIGluIHRoaXMgZnVuY3Rpb24gOgogKglvIGZpcnN0IG1ha2Ugc3VyZSB0aGF0IHRoZSBkb25nbGUgaXMgaW4gYSBzdGF0ZSB3aGVyZSBpdCBjYW4gb3BlcmF0ZQogKglvIHNlY29uZCBwdXQgdGhlIGRvbmdsZSBpbiBhIGtub3cgc3RhdGUKICoKICoJVGhlIGRvbmdsZSBpcyBwb3dlcmVkIG9mIHRoZSBSVFMgYW5kIERUUiBsaW5lcy4gSW4gdGhlIGRvbmdsZSwgdGhlcmUKICogaXMgYSBiaWcgY2FwYWNpdG9yIHRvIGFjY29tbW9kYXRlIHRoZSBjdXJyZW50IHNwaWtlcy4gVGhpcyBjYXBhY2l0b3IKICogdGFrZXMgYSBsZWFzdCA1MCBtcyB0byBiZSBjaGFyZ2VkLiBJbiB0aGVvcnksIHRoZSBCaW9zIHNldCB0aG9zZSBsaW5lcwogKiB1cCwgc28gYnkgdGhlIHRpbWUgd2UgYXJyaXZlIGhlcmUgd2Ugc2hvdWxkIGJlIHNldC4gSXQgZG9lc24ndCBodXJ0CiAqIHRvIGJlIG9uIHRoZSBjb25zZXJ2YXRpdmUgc2lkZSwgc28gd2Ugd2lsbCB3YWl0Li4uCiAqIDxNYXJ0aW4gOiBtb3ZlIGFib3ZlIGNvbW1lbnQgdG8gaXJkYV9jb25maWdfZnNtPgogKglUaGVuLCB3ZSBzZXQgdGhlIHNwZWVkIHRvIDk2MDAgYi9zIHRvIGdldCBpbiBhIGtub3duIHN0YXRlIChzZWUgaW4KICogY2hhbmdlX3NwZWVkIGZvciBkZXRhaWxzKS4gSXQgaXMgbmVlZGVkIGJlY2F1c2UgdGhlIElyREEgc3RhY2sKICogaGFzIHRyaWVkIHRvIHNldCB0aGUgc3BlZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgb3VyIGZpcnN0IHJldHVybiwKICogc28gYmVmb3JlIHdlIGNhbiBiZSBzdXJlIHRoZSBkb25nbGUgaXMgdXAgYW5kIHJ1bm5pbmcuCiAqLwoKc3RhdGljIGludCBhY3Rpc3lzX3Jlc2V0KHN0cnVjdCBzaXJfZGV2ICpkZXYpCnsKCS8qIFJlc2V0IHRoZSBkb25nbGUgOiBzZXQgRFRSIGxvdyBmb3IgMTAgdXMgKi8KCXNpcmRldl9zZXRfZHRyX3J0cyhkZXYsIEZBTFNFLCBUUlVFKTsKCXVkZWxheShNSU5fREVMQVkpOwoKCS8qIEdvIGJhY2sgdG8gbm9ybWFsIG1vZGUgKi8KCXNpcmRldl9zZXRfZHRyX3J0cyhkZXYsIFRSVUUsIFRSVUUpOwoJCglkZXYtPnNwZWVkID0gOTYwMDsJLyogVGhhdCdzIHRoZSBkZWZhdWx0ICovCgoJcmV0dXJuIDA7Cn0KCk1PRFVMRV9BVVRIT1IoIkRhZyBCcmF0dGxpIDxkYWdiQGNzLnVpdC5ubz4gLSBKZWFuIFRvdXJyaWxoZXMgPGp0QGhwbC5ocC5jb20+Iik7Ck1PRFVMRV9ERVNDUklQVElPTigiQUNUaVNZUyBJUi0yMjBMIGFuZCBJUi0yMjBMKyBkb25nbGUgZHJpdmVyIik7CQpNT0RVTEVfTElDRU5TRSgiR1BMIik7Ck1PRFVMRV9BTElBUygiaXJkYS1kb25nbGUtMiIpOyAvKiBJUkRBX0FDVElTWVNfRE9OR0xFICovCk1PRFVMRV9BTElBUygiaXJkYS1kb25nbGUtMyIpOyAvKiBJUkRBX0FDVElTWVNfUExVU19ET05HTEUgKi8KCm1vZHVsZV9pbml0KGFjdGlzeXNfc2lyX2luaXQpOwptb2R1bGVfZXhpdChhY3Rpc3lzX3Npcl9jbGVhbnVwKTsK