LyoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChDKSAxOTk2LTIwMDAsIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kICAgICoKICogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogJFNvdXJjZTogL3hzcmwvTnN2bi9pY3UvaWN1NGovc3JjL2NvbS9pYm0vaWN1L3RleHQvU3RyaW5nU2VhcmNoLmphdmEsdiAkIAogKiAkRGF0ZTogMjAwMi8wNy8xMiAyMTo1OToyMiAkIAogKiAkUmV2aXNpb246IDEuOSAkCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKi8KCnBhY2thZ2UgY29tLmlibS5pY3UudGV4dDsKCmltcG9ydCBqYXZhLnRleHQuQ2hhcmFjdGVySXRlcmF0b3I7CmltcG9ydCBqYXZhLnRleHQuU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwppbXBvcnQgY29tLmlibS5pY3UubGFuZy5VQ2hhcmFjdGVyOwppbXBvcnQgY29tLmlibS5pY3UuaW1wbC5Ob3JtYWxpemVySW1wbDsKCi8qKgogKiA8cD4KICogPGNvZGU+U3RyaW5nU2VhcmNoPC9jb2RlPiBpcyB0aGUgY29uY3JldGUgc3ViY2xhc3Mgb2YgCiAqIDxjb2RlPlNlYXJjaEl0ZXJhdG9yPC9jb2RlPiB0aGF0IHByb3ZpZGVzIGxhbmd1YWdlLXNlbnNpdGl2ZSB0ZXh0IHNlYXJjaGluZyAKICogYmFzZWQgb24gdGhlIGNvbXBhcmlzb24gcnVsZXMgZGVmaW5lZCBpbiBhIHtAbGluayBSdWxlQmFzZWRDb2xsYXRvcn0gb2JqZWN0LgogKiA8L3A+CiAqIDxwPgogKiA8Y29kZT5TdHJpbmdTZWFyY2g8L2NvZGU+IHVzZXMgYSB2ZXJzaW9uIG9mIHRoZSBmYXN0IEJveWVyLU1vb3JlIHNlYXJjaAogKiBhbGdvcml0aG0gdGhhdCBoYXMgYmVlbiBhZGFwdGVkIHRvIHdvcmsgd2l0aCB0aGUgbGFyZ2UgY2hhcmFjdGVyIHNldCBvZgogKiBVbmljb2RlLiBSZWZlciB0byAKICogPGEgaHJlZj1odHRwOi8vb3NzLnNvZnR3YXJlLmlibS5jb20vaWN1L2RvY3MvcGFwZXJzL2VmZmljaWVudF90ZXh0X3NlYXJjaGluZ19pbl9qYXZhLmh0bWw+CiAqICJFZmZpY2llbnQgVGV4dCBTZWFyY2hpbmcgaW4gSmF2YSI8L2E+LCBwdWJsaXNoZWQgaW4gdGhlIAogKiA8aT5KYXZhIFJlcG9ydDwvaT4gb24gRmVicnVhcnksIDE5OTksIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uIG9uIHRoZSAKICogYWxnb3JpdGhtLgogKiA8L3A+CiAqIDxwPgogKiBVc2VycyBhcmUgYWxzbyBzdHJvbmdseSBlbmNvdXJhZ2VkIHRvIHJlYWQgdGhlIHNlY3Rpb24gb24gCiAqIDxhIGhyZWY9aHR0cDovL29zcy5zb2Z0d2FyZS5pYm0uY29tL2ljdS91c2VyZ3VpZGUvc2VhcmNoU3RyaW5nLmh0bWw+CiAqIFN0cmluZyBTZWFyY2g8L2E+IGFuZCAKICogPGEgaHJlZj1odHRwOi8vb3NzLnNvZnR3YXJlLmlibS5jb20vaWN1L3VzZXJndWlkZS9Db2xsYXRlX0ludHJvLmh0bWw+CiAqIENvbGxhdGlvbjwvYT4gaW4gdGhlIHVzZXIgZ3VpZGUgYmVmb3JlIGF0dGVtcHRpbmcgdG8gdXNlIHRoaXMgY2xhc3MuCiAqIDwvcD4KICogPHA+CiAqIFN0cmluZyBzZWFyY2hpbmcgZ2V0cyBhbGl0dGxlIGNvbXBsaWNhdGVkIHdoZW4gYWNjZW50cyBhcmUgZW5jb3VudGVyZWQgYXQKICogbWF0Y2ggYm91bmRhcmllcy4gSWYgYSBtYXRjaCBpcyBmb3VuZCBhbmQgaXQgaGFzIHByZWNlZGluZyBvciB0cmFpbGluZyAKICogYWNjZW50cyBub3QgcGFydCBvZiB0aGUgbWF0Y2gsIHRoZSByZXN1bHQgcmV0dXJuZWQgd2lsbCBpbmNsdWRlIHRoZSAKICogcHJlY2VkaW5nIGFjY2VudHMgdXAgdG8gdGhlIGZpcnN0IGJhc2UgY2hhcmFjdGVyLCBpZiB0aGUgcGF0dGVybiBzZWFyY2hlZCAKICogZm9yIHN0YXJ0cyBhbiBhY2NlbnQuIExpa2V3aXNlLCAKICogaWYgdGhlIHBhdHRlcm4gZW5kcyB3aXRoIGFuIGFjY2VudCwgYWxsIHRyYWlsaW5nIGFjY2VudHMgdXAgdG8gdGhlIGZpcnN0CiAqIGJhc2UgY2hhcmFjdGVyIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIHJlc3VsdC4KICogPC9wPgogKiA8cD4KICogRm9yIGV4YW1wbGUsIGlmIGEgbWF0Y2ggaXMgZm91bmQgaW4gdGFyZ2V0IHRleHQgImEmIzkyO3UwMzI1JiM5Mjt1MDMwMCIgZm9yIAogKiB0aGUgcGF0dGVybgogKiAiYSYjOTI7dTAzMjUiLCB0aGUgcmVzdWx0IHJldHVybmVkIGJ5IFN0cmluZ1NlYXJjaCB3aWxsIGJlIHRoZSBpbmRleCAwIGFuZAogKiBsZW5ndGggMyAmbHQ7MCwgMyZndDsuIElmIGEgbWF0Y2ggaXMgZm91bmQgaW4gdGhlIHRhcmdldCAKICogImEmIzkyO3UwMzI1JiM5Mjt1MDMwMCIgCiAqIGZvciB0aGUgcGF0dGVybiAiJiM5Mjt1MDMwMCIsIHRoZW4gdGhlIHJlc3VsdCB3aWxsIGJlIGluZGV4IDEgYW5kIGxlbmd0aCAyIAogKiA8MSwgMj4uCiAqIDwvcD4KICogPHA+CiAqIEluIHRoZSBjYXNlIHdoZXJlIHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUgaXMgb24gZm9yIHRoZSBSdWxlQmFzZWRDb2xsYXRvciwKICogYWxsIG1hdGNoZXMgdGhhdCBzdGFydHMgb3IgZW5kcyB3aXRoIGFuIGFjY2VudCB3aWxsIGhhdmUgaXRzIHJlc3VsdHMgaW5jbHVkZSAKICogcHJlY2VkaW5nIG9yIGZvbGxvd2luZyBhY2NlbnRzIHJlc3BlY3RpdmVseS4gRm9yIGV4YW1wbGUsIGlmIHBhdHRlcm4gImEiIGlzCiAqIGxvb2tlZCBmb3IgaW4gdGhlIHRhcmdldCB0ZXh0ICImYWFjdXRlOyYjOTI7dTAzMjUiLCB0aGUgcmVzdWx0IHdpbGwgYmUKICogaW5kZXggMCBhbmQgbGVuZ3RoIDIgJmx0OzAsIDImZ3Q7LgogKiA8L3A+CiAqIDxwPgogKiBUaGUgU3RyaW5nU2VhcmNoIGNsYXNzIHByb3ZpZGVzIHR3byBvcHRpb25zIHRvIGhhbmRsZSBhY2NlbnQgbWF0Y2hpbmcgCiAqIGRlc2NyaWJlZCBiZWxvdzoKICogPC9wPgogKiA8cD4KICogTGV0IFMnIGJlIHRoZSBzdWItc3RyaW5nIG9mIGEgdGV4dCBzdHJpbmcgUyBiZXR3ZWVuIHRoZSBvZmZzZXRzIHN0YXJ0IGFuZCAKICogZW5kICZsdDtzdGFydCwgZW5kJmd0Oy4KICogPGJyPgogKiBBIHBhdHRlcm4gc3RyaW5nIFAgbWF0Y2hlcyBhIHRleHQgc3RyaW5nIFMgYXQgdGhlIG9mZnNldHMgJmx0O3N0YXJ0LCAKICogbGVuZ3RoJmd0OyAKICogPGJyPgogKiBpZgogKiA8cHJlPiAKICogb3B0aW9uIDEuIFAgbWF0Y2hlcyBzb21lIGNhbm9uaWNhbCBlcXVpdmFsZW50IHN0cmluZyBvZiBTJy4gU3VwcG9zZSB0aGUgCiAqICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvciB1c2VkIGZvciBzZWFyY2hpbmcgaGFzIGEgY29sbGF0aW9uIHN0cmVuZ3RoIG9mIAogKiAgICAgICAgICAgVEVSVElBUlksIGFsbCBhY2NlbnRzIGFyZSBub24taWdub3JhYmxlLiBJZiB0aGUgcGF0dGVybiAKICogICAgICAgICAgICJhJiM5Mjt1MDMwMCIgaXMgc2VhcmNoZWQgaW4gdGhlIHRhcmdldCB0ZXh0IAogKiAgICAgICAgICAgImEmIzkyO3UwMzI1JiM5Mjt1MDMwMCIsIAogKiAgICAgICAgICAgYSBtYXRjaCB3aWxsIGJlIGZvdW5kLCBzaW5jZSB0aGUgdGFyZ2V0IHRleHQgaXMgY2Fub25pY2FsbHkgCiAqICAgICAgICAgICBlcXVpdmFsZW50IHRvICJhJiM5Mjt1MDMwMCYjOTI7dTAzMjUiCiAqIG9wdGlvbiAyLiBQIG1hdGNoZXMgUycgYW5kIGlmIFAgc3RhcnRzIG9yIGVuZHMgd2l0aCBhIGNvbWJpbmluZyBtYXJrLCAKICogICAgICAgICAgIHRoZXJlIGV4aXN0cyBubyBub24taWdub3JhYmxlIGNvbWJpbmluZyBtYXJrIGJlZm9yZSBvciBhZnRlciBTkiAKICogICAgICAgICAgIGluIFMgcmVzcGVjdGl2ZWx5LiBGb2xsb3dpbmcgdGhlIGV4YW1wbGUgYWJvdmUsIHRoZSBwYXR0ZXJuIAogKiAgICAgICAgICAgImEmIzkyO3UwMzAwIiB3aWxsIG5vdCBmaW5kIGEgbWF0Y2ggaW4gImEmIzkyO3UwMzI1JiM5Mjt1MDMwMCIsIAogKiAgICAgICAgICAgc2luY2UKICogICAgICAgICAgIHRoZXJlIGV4aXN0cyBhIG5vbi1pZ25vcmFibGUgYWNjZW50ICcmIzkyO3UwMzI1JyBpbiB0aGUgbWlkZGxlIG9mIAogKiAgICAgICAgICAgJ2EnIGFuZCAnJiM5Mjt1MDMwMCcuIEV2ZW4gd2l0aCBhIHRhcmdldCB0ZXh0IG9mIAogKiAgICAgICAgICAgImEmIzkyO3UwMzAwJiM5Mjt1MDMyNSIgYSBtYXRjaCB3aWxsIG5vdCBiZSBmb3VuZCBiZWNhdXNlIG9mIHRoZSAKICogICAgICAgICAgIG5vbi1pZ25vcmFibGUgdHJhaWxpbmcgYWNjZW50ICYjOTI7dTAzMjUuCiAqIDwvcHJlPgogKiBPcHRpb24gMi4gd2lsbCBiZSB0aGUgZGVmYXVsdCBtb2RlIGZvciBkZWFsaW5nIHdpdGggYm91bmRhcnkgYWNjZW50cyB1bmxlc3MKICogc3BlY2lmaWVkIHZpYSB0aGUgQVBJIHNldENhbm9uaWNhbChib29sZWFuKS4KICogT25lIHJlc3RyaWN0aW9uIGlzIHRvIGJlIG5vdGVkIGZvciBvcHRpb24gMS4gQ3VycmVudGx5IHRoZXJlIGFyZSBubyAKICogY29tcG9zaXRlIGNoYXJhY3RlcnMgdGhhdCBjb25zaXN0cyBvZiBhIGNoYXJhY3RlciB3aXRoIGNvbWJpbmluZyBjbGFzcyA+IDAgCiAqIGJlZm9yZSBhIGNoYXJhY3RlciB3aXRoIGNvbWJpbmluZyBjbGFzcyA9PSAwLiBIb3dldmVyLCBpZiBzdWNoIGEgY2hhcmFjdGVyIAogKiBleGlzdHMgaW4gdGhlIGZ1dHVyZSwgdGhlIFN0cmluZ1NlYXJjaCBtYXkgbm90IHdvcmsgY29ycmVjdGx5IHdpdGggb3B0aW9uIDEKICogd2hlbiBzdWNoIGNoYXJhY3RlcnMgYXJlIGVuY291bnRlcmVkLgogKiA8L3A+CiAqIDxwPgogKiA8dHQ+U2VhcmNoSXRlcmF0b3I8L3R0PiBwcm92aWRlcyBBUElzIHRvIHNwZWNpZnkgdGhlIHN0YXJ0aW5nIHBvc2l0aW9uIAogKiB3aXRoaW4gdGhlIHRleHQgc3RyaW5nIHRvIGJlIHNlYXJjaGVkLCBlLmcuIDx0dD5zZXRJbmRleDwvdHQ+LAogKiA8dHQ+cHJlY2VkaW5nPC90dD4gYW5kIDx0dD5mb2xsb3dpbmc8L3R0Pi4gU2luY2UgdGhlIHN0YXJ0aW5nIHBvc2l0aW9uIHdpbGwgCiAqIGJlIHNldCBhcyBpdCBpcyBzcGVjaWZpZWQsIHBsZWFzZSB0YWtlIG5vdGUgdGhhdCB0aGVyZSBhcmUgc29tZSBkYW5nZXJvdXMgCiAqIHBvc2l0aW9ucyB3aGljaCB0aGUgc2VhcmNoIG1heSByZW5kZXIgaW5jb3JyZWN0IHJlc3VsdHM6CiAqIDx1bD4KICogPGxpPiBUaGUgbWlkc3Qgb2YgYSBzdWJzdHJpbmcgdGhhdCByZXF1aXJlcyBkZWNvbXBvc2l0aW9uLgogKiA8bGk+IElmIHRoZSBmb2xsb3dpbmcgbWF0Y2ggaXMgdG8gYmUgZm91bmQsIHRoZSBwb3NpdGlvbiBzaG91bGQgbm90IGJlIHRoZQogKiAgICAgIHNlY29uZCBjaGFyYWN0ZXIgd2hpY2ggcmVxdWlyZXMgdG8gYmUgc3dhcHBlZCB3aXRoIHRoZSBwcmVjZWRpbmcgCiAqICAgICAgY2hhcmFjdGVyLiBWaWNlIHZlcnNhLCBpZiB0aGUgcHJlY2VkaW5nIG1hdGNoIGlzIHRvIGJlIGZvdW5kLCAKICogICAgICBwb3NpdGlvbiB0byBzZWFyY2ggZnJvbSBzaG91bGQgbm90IGJlIHRoZSBmaXJzdCBjaGFyYWN0ZXIgd2hpY2ggCiAqICAgICAgcmVxdWlyZXMgdG8gYmUgc3dhcHBlZCB3aXRoIHRoZSBuZXh0IGNoYXJhY3Rlci4gRS5nIGNlcnRhaW4gVGhhaSBhbmQKICogICAgICBMYW8gY2hhcmFjdGVycyByZXF1aXJlIHN3YXBwaW5nLgogKiA8bGk+IElmIGEgZm9sbG93aW5nIHBhdHRlcm4gbWF0Y2ggaXMgdG8gYmUgZm91bmQsIGFueSBwb3NpdGlvbiB3aXRoaW4gYSAKICogICAgICBjb250cmFjdGluZyBzZXF1ZW5jZSBleGNlcHQgdGhlIGZpcnN0IHdpbGwgZmFpbC4gVmljZSB2ZXJzYSBpZiBhIAogKiAgICAgIHByZWNlZGluZyBwYXR0ZXJuIG1hdGNoIGlzIHRvIGJlIGZvdW5kLCBhIGludmFsaWQgc3RhcnRpbmcgcG9pbnQgCiAqICAgICAgd291bGQgYmUgYW55IGNoYXJhY3RlciB3aXRoaW4gYSBjb250cmFjdGluZyBzZXF1ZW5jZSBleGNlcHQgdGhlIGxhc3QuCiAqIDwvdWw+CiAqIDwvcD4KICogPHA+CiAqIFRob3VnaCBjb2xsYXRvciBhdHRyaWJ1dGVzIHdpbGwgYmUgdGFrZW4gaW50byBjb25zaWRlcmF0aW9uIHdoaWxlIAogKiBwZXJmb3JtaW5nIG1hdGNoZXMsIHRoZXJlIGFyZSBubyBBUElzIHByb3ZpZGVkIGluIFN0cmluZ1NlYXJjaCBmb3Igc2V0dGluZyAKICogYW5kIGdldHRpbmcgdGhlIGF0dHJpYnV0ZXMuIFRoZXNlIGF0dHJpYnV0ZXMgY2FuIGJlIHNldCBieSBnZXR0aW5nIHRoZSAKICogY29sbGF0b3IgZnJvbSA8dHQ+Z2V0Q29sbGF0b3I8L3R0PiBhbmQgdXNpbmcgdGhlIEFQSXMgaW4gCiAqIDx0dD5jb20uaWJtLmljdS50ZXh0LkNvbGxhdG9yPC90dD4uIFRvIHVwZGF0ZSBTdHJpbmdTZWFyY2ggdG8gdGhlIG5ldyAKICogY29sbGF0b3IgYXR0cmlidXRlcywgPHR0PnJlc2V0KCk8L3R0PiBvciAKICogPHR0PnNldENvbGxhdG9yKFJ1bGVCYXNlZENvbGxhdG9yKTwvdHQ+IGhhcyB0byBiZSBjYWxsZWQuCiAqIDwvcD4KICogPHA+CiAqIENvbnN1bHQgdGhlIAogKiA8YSBocmVmPWh0dHA6Ly9vc3Muc29mdHdhcmUuaWJtLmNvbS9pY3UvdXNlcmd1aWRlL3NlYXJjaFN0cmluZy5odG1sPgogKiBTdHJpbmcgU2VhcmNoPC9hPiB1c2VyIGd1aWRlIGFuZCB0aGUgPGNvZGU+U2VhcmNoSXRlcmF0b3I8L2NvZGU+IAogKiBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uIGFuZCBleGFtcGxlcyBvZiB1c2UuCiAqIDwvcD4KICogQHNlZSBTZWFyY2hJdGVyYXRvcgogKiBAc2VlIFJ1bGVCYXNlZENvbGxhdG9yCiAqIEBhdXRob3IgTGF1cmEgV2VybmVyLCBzeW53ZWUKICogQHNpbmNlIDEuMAogKi8KLy8gaW50ZXJuYWwgbm90ZXM6IGFsbCBtZXRob2RzIGRvIG5vdCBndWFyYW50ZWUgdGhlIGNvcnJlY3Qgc3RhdHVzIG9mIHRoZSAKLy8gY2hhcmFjdGVyaXRlcmF0b3IuIHRoZSBjYWxsZXIgaGFzIHRvIG1haW50YWluIHRoZSBvcmlnaW5hbCBpbmRleCBwb3NpdGlvbgovLyBpZiBuZWNlc3NhcnkuIG1ldGhvZHMgY291bGQgY2hhbmdlIHRoZSBpbmRleCBwb3NpdGlvbiBhcyBpdCBkZWVtcyBmaXQKcHVibGljIGZpbmFsIGNsYXNzIFN0cmluZ1NlYXJjaCBleHRlbmRzIFNlYXJjaEl0ZXJhdG9yCnsKCQoJLy8gcHVibGljIGNvbnN0cnVjdG9ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJCiAgICAvKioKICAgICAqIEluaXRpYWxpemVzIHRoZSBpdGVyYXRvciB0byB1c2UgdGhlIGxhbmd1YWdlLXNwZWNpZmljIHJ1bGVzIGRlZmluZWQgaW4gCiAgICAgKiB0aGUgYXJndW1lbnQgY29sbGF0b3IgdG8gc2VhcmNoIGZvciBhcmd1bWVudCBwYXR0ZXJuIGluIHRoZSBhcmd1bWVudCAKICAgICAqIHRhcmdldCB0ZXh0LiBUaGUgYXJndW1lbnQgYnJlYWtpdGVyIGlzIHVzZWQgdG8gZGVmaW5lIGxvZ2ljYWwgbWF0Y2hlcy4KICAgICAqIFNlZSBzdXBlciBjbGFzcyBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGRldGFpbHMgb24gdGhlIHVzZSBvZiB0aGUgdGFyZ2V0IAogICAgICogdGV4dCBhbmQgQnJlYWtJdGVyYXRvci4KICAgICAqIEBwYXJhbSBwYXR0ZXJuIHRleHQgdG8gbG9vayBmb3IuCiAgICAgKiBAcGFyYW0gdGFyZ2V0IHRhcmdldCB0ZXh0IHRvIHNlYXJjaCBmb3IgcGF0dGVybi4gCiAgICAgKiBAcGFyYW0gY29sbGF0b3IgUnVsZUJhc2VkQ29sbGF0b3IgdGhhdCBkZWZpbmVzIHRoZSBsYW5ndWFnZSBydWxlcwogICAgICogQHBhcmFtIGJyZWFrZXIgQSB7QGxpbmsgQnJlYWtJdGVyYXRvcn0gdGhhdCBpcyB1c2VkIHRvIGRldGVybWluZSB0aGUgCiAgICAgKiAgICAgICAgICAgICAgICBib3VuZGFyaWVzIG9mIGEgbG9naWNhbCBtYXRjaC4gVGhpcyBhcmd1bWVudCBjYW4gYmUgbnVsbC4KICAgICAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHRocm93biB3aGVuIGFyZ3VtZW50IHRhcmdldCBpcyBudWxsLAogICAgICogICAgICAgICAgICBvciBvZiBsZW5ndGggMAogICAgICogQHNlZSBCcmVha0l0ZXJhdG9yCiAgICAgKiBAc2VlIFJ1bGVCYXNlZENvbGxhdG9yCiAgICAgKiBAc2VlIFNlYXJjaEl0ZXJhdG9yCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmdTZWFyY2goU3RyaW5nIHBhdHRlcm4sIENoYXJhY3Rlckl0ZXJhdG9yIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IgY29sbGF0b3IsIEJyZWFrSXRlcmF0b3IgYnJlYWtpdGVyKSAKICAgIHsKICAgICAgICBzdXBlcih0YXJnZXQsIGJyZWFraXRlcik7CiAgICAgICAgbV90ZXh0QmVnaW5PZmZzZXRfID0gdGFyZ2V0VGV4dC5nZXRCZWdpbkluZGV4KCk7CiAgICAgICAgbV90ZXh0TGltaXRPZmZzZXRfID0gdGFyZ2V0VGV4dC5nZXRFbmRJbmRleCgpOwogICAgICAgIG1fY29sbGF0b3JfID0gY29sbGF0b3I7CiAgICAgICAgbV9jb2xFSXRlcl8gPSBtX2NvbGxhdG9yXy5nZXRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IodGFyZ2V0KTsKICAgICAgICBtX3V0aWxDb2xFSXRlcl8gPSBjb2xsYXRvci5nZXRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoIiIpOwogICAgICAgIG1fY2VNYXNrXyA9IGdldE1hc2sobV9jb2xsYXRvcl8uZ2V0U3RyZW5ndGgoKSk7CiAgICAgICAgbV9pc0Nhbm9uaWNhbE1hdGNoXyA9IGZhbHNlOwogICAgICAgIG1fcGF0dGVybl8gPSBuZXcgUGF0dGVybihwYXR0ZXJuKTsKICAgICAgICBtX21hdGNoZWRJbmRleF8gPSBET05FOwogICAgICAgIAogICAgICAgIGluaXRpYWxpemUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEluaXRpYWxpemVzIHRoZSBpdGVyYXRvciB0byB1c2UgdGhlIGxhbmd1YWdlLXNwZWNpZmljIHJ1bGVzIGRlZmluZWQgaW4gCiAgICAgKiB0aGUgYXJndW1lbnQgY29sbGF0b3IgdG8gc2VhcmNoIGZvciBhcmd1bWVudCBwYXR0ZXJuIGluIHRoZSBhcmd1bWVudCAKICAgICAqIHRhcmdldCB0ZXh0LiBObyBCcmVha0l0ZXJhdG9ycyBhcmUgc2V0IHRvIHRlc3QgZm9yIGxvZ2ljYWwgbWF0Y2hlcy4KICAgICAqIEBwYXJhbSBwYXR0ZXJuIHRleHQgdG8gbG9vayBmb3IuCiAgICAgKiBAcGFyYW0gdGFyZ2V0IHRhcmdldCB0ZXh0IHRvIHNlYXJjaCBmb3IgcGF0dGVybi4gCiAgICAgKiBAcGFyYW0gY29sbGF0b3IgUnVsZUJhc2VkQ29sbGF0b3IgdGhhdCBkZWZpbmVzIHRoZSBsYW5ndWFnZSBydWxlcwogICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gdGhyb3duIHdoZW4gYXJndW1lbnQgdGFyZ2V0IGlzIG51bGwsCiAgICAgKiAgICAgICAgICAgIG9yIG9mIGxlbmd0aCAwCiAgICAgKiBAc2VlIFJ1bGVCYXNlZENvbGxhdG9yCiAgICAgKiBAc2VlIFNlYXJjaEl0ZXJhdG9yCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmdTZWFyY2goU3RyaW5nIHBhdHRlcm4sIENoYXJhY3Rlckl0ZXJhdG9yIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IgY29sbGF0b3IpIAogICAgewogICAgICAgIHRoaXMocGF0dGVybiwgdGFyZ2V0LCBjb2xsYXRvciwgQnJlYWtJdGVyYXRvci5nZXRDaGFyYWN0ZXJJbnN0YW5jZSgpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEluaXRpYWxpemVzIHRoZSBpdGVyYXRvciB0byB1c2UgdGhlIGxhbmd1YWdlLXNwZWNpZmljIHJ1bGVzIGFuZCAKICAgICAqIGJyZWFrIGl0ZXJhdG9yIHJ1bGVzIGRlZmluZWQgaW4gdGhlIGFyZ3VtZW50IGxvY2FsZSB0byBzZWFyY2ggZm9yIAogICAgICogYXJndW1lbnQgcGF0dGVybiBpbiB0aGUgYXJndW1lbnQgdGFyZ2V0IHRleHQuIAogICAgICogU2VlIHN1cGVyIGNsYXNzIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgZGV0YWlscyBvbiB0aGUgdXNlIG9mIHRoZSB0YXJnZXQgCiAgICAgKiB0ZXh0IGFuZCBCcmVha0l0ZXJhdG9yLgogICAgICogQHBhcmFtIHBhdHRlcm4gdGV4dCB0byBsb29rIGZvci4KICAgICAqIEBwYXJhbSB0YXJnZXQgdGFyZ2V0IHRleHQgdG8gc2VhcmNoIGZvciBwYXR0ZXJuLiAKICAgICAqIEBwYXJhbSBsb2NhbGUgbG9jYWxlIHRvIHVzZSBmb3IgbGFuZ3VhZ2UgYW5kIGJyZWFrIGl0ZXJhdG9yIHJ1bGVzCiAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB0aHJvd24gd2hlbiBhcmd1bWVudCB0YXJnZXQgaXMgbnVsbCwKICAgICAqICAgICAgICAgICAgb3Igb2YgbGVuZ3RoIDAuIENsYXNzQ2FzdEV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIGNvbGxhdG9yIGZvciAKICAgICAqICAgICAgICAgICAgdGhlIHNwZWNpZmllZCBsb2NhbGUgaXMgbm90IGEgUnVsZUJhc2VkQ29sbGF0b3IuCiAgICAgKiBAc2VlIEJyZWFrSXRlcmF0b3IKICAgICAqIEBzZWUgUnVsZUJhc2VkQ29sbGF0b3IKICAgICAqIEBzZWUgU2VhcmNoSXRlcmF0b3IKICAgICAqLwogICAgcHVibGljIFN0cmluZ1NlYXJjaChTdHJpbmcgcGF0dGVybiwgQ2hhcmFjdGVySXRlcmF0b3IgdGFyZ2V0LCBMb2NhbGUgbG9jYWxlKQogICAgewogICAgICAgIHRoaXMocGF0dGVybiwgdGFyZ2V0LCAoUnVsZUJhc2VkQ29sbGF0b3IpQ29sbGF0b3IuZ2V0SW5zdGFuY2UobG9jYWxlKSwKICAgICAgICAgICAgIEJyZWFrSXRlcmF0b3IuZ2V0Q2hhcmFjdGVySW5zdGFuY2UobG9jYWxlKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyB0aGUgaXRlcmF0b3IgdG8gdXNlIHRoZSBsYW5ndWFnZS1zcGVjaWZpYyBydWxlcyBhbmQgCiAgICAgKiBicmVhayBpdGVyYXRvciBydWxlcyBkZWZpbmVkIGluIHRoZSBkZWZhdWx0IGxvY2FsZSB0byBzZWFyY2ggZm9yIAogICAgICogYXJndW1lbnQgcGF0dGVybiBpbiB0aGUgYXJndW1lbnQgdGFyZ2V0IHRleHQuIAogICAgICogU2VlIHN1cGVyIGNsYXNzIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgZGV0YWlscyBvbiB0aGUgdXNlIG9mIHRoZSB0YXJnZXQgCiAgICAgKiB0ZXh0IGFuZCBCcmVha0l0ZXJhdG9yLgogICAgICogQHBhcmFtIHBhdHRlcm4gdGV4dCB0byBsb29rIGZvci4KICAgICAqIEBwYXJhbSB0YXJnZXQgdGFyZ2V0IHRleHQgdG8gc2VhcmNoIGZvciBwYXR0ZXJuLiAKICAgICAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHRocm93biB3aGVuIGFyZ3VtZW50IHRhcmdldCBpcyBudWxsLAogICAgICogICAgICAgICAgICBvciBvZiBsZW5ndGggMC4gQ2xhc3NDYXN0RXhjZXB0aW9uIHRocm93biBpZiB0aGUgY29sbGF0b3IgZm9yIAogICAgICogICAgICAgICAgICB0aGUgZGVmYXVsdCBsb2NhbGUgaXMgbm90IGEgUnVsZUJhc2VkQ29sbGF0b3IuCiAgICAgKiBAc2VlIEJyZWFrSXRlcmF0b3IKICAgICAqIEBzZWUgUnVsZUJhc2VkQ29sbGF0b3IKICAgICAqIEBzZWUgU2VhcmNoSXRlcmF0b3IKICAgICAqLwogICAgcHVibGljIFN0cmluZ1NlYXJjaChTdHJpbmcgcGF0dGVybiwgU3RyaW5nIHRhcmdldCkgCiAgICB7CiAgICAgICAgdGhpcyhwYXR0ZXJuLCBuZXcgU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3IodGFyZ2V0KSwKICAgICAgICAgICAgIChSdWxlQmFzZWRDb2xsYXRvcilDb2xsYXRvci5nZXRJbnN0YW5jZSgpLAogICAgICAgICAgICAgQnJlYWtJdGVyYXRvci5nZXRDaGFyYWN0ZXJJbnN0YW5jZSgpKTsKICAgIH0KCiAgICAvLyBwdWJsaWMgZ2V0dGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHN0cmVuZ3RoIHByb3BlcnR5IG9mIHRoZSBSdWxlQmFzZWRDb2xsYXRvciB1c2VkIGluIHNlYXJjaGluZy4gCiAgICAgKiBTZWUgdGhlIFJ1bGVCYXNlZENvbGxhdG9yIGNsYXNzIGRvY3VtZW50YXRpb24gZm9yIGEgZGVzY3JpcHRpb24gb2YgdGhlCiAgICAgKiBzdHJlbmd0aCBwcm9wZXJ0eS4KICAgICAqIEByZXR1cm4gdGhlIHN0cmVuZ3RoIHByb3BlcnR5IG9mIHRoZSBSdWxlQmFzZWRDb2xsYXRvciB1c2VkIGluIHNlYXJjaGluZwogICAgICogQHNlZSBSdWxlQmFzZWRDb2xsYXRvcgogICAgICogQHNlZSAjc2V0U3RyZW5ndGgKICAgICAqIEBzZWUgI2dldENvbGxhdG9yCiAgICAgKiBAZGVwcmVjYXRlZCBzaW5jZSByZWxlYXNlIDIuMiwgdXNlciB3aG8gd291bGQgbGlrZSB0byBhY2Nlc3MgdGhlIAogICAgICogICAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3Igc3RyZW5ndGgsIHNob3VsZCByZXRyaWV2ZSB0aGUgCiAgICAgKiAgICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvciB2aWEgdGhlIEFQSSBnZXRDb2xsYXRvcigpLCBhbmQgdXNlIHRoZSAKICAgICAqICAgICAgICAgICAgIENvbGxhdG9yIEFQSXMgdG8gcmV0cmlldmUgdGhlIHN0cmVuZ3RoLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFN0cmVuZ3RoKCkgewogICAgICAgIHJldHVybiBtX2NvbGxhdG9yXy5nZXRTdHJlbmd0aCgpOwogICAgfQogICAgCiAgICAvKioKCSAqIDxwPgogICAgICogR2V0cyB0aGUgUnVsZUJhc2VkQ29sbGF0b3IgdXNlZCBmb3IgdGhlIGxhbmd1YWdlIHJ1bGVzLgogICAgICogPC9wPgoJICogPHA+CiAgICAgKiBTaW5jZSBTdHJpbmdTZWFyY2ggZGVwZW5kcyBvbiB0aGUgcmV0dXJuZWQgUnVsZUJhc2VkQ29sbGF0b3IsIGFueSAKCSAqIGNoYW5nZXMgdG8gdGhlIFJ1bGVCYXNlZENvbGxhdG9yIHJlc3VsdCBzaG91bGQgZm9sbG93IHdpdGggYSBjYWxsIHRvIAoJICogZWl0aGVyIFN0cmluZ1NlYXJjaC5yZXNldCgpIG9yIAoJICogU3RyaW5nU2VhcmNoLnNldENvbGxhdG9yKFJ1bGVCYXNlZENvbGxhdG9yKSB0byBlbnN1cmUgdGhlIGNvcnJlY3QgCgkgKiBzZWFyY2ggYmVoYXZpb3VyLgogICAgICogPC9wPgoJICogQHJldHVybiBSdWxlQmFzZWRDb2xsYXRvciB1c2VkIGJ5IHRoaXMgU3RyaW5nU2VhcmNoCiAgICAgKiBAc2VlIFJ1bGVCYXNlZENvbGxhdG9yCiAgICAgKiBAc2VlICNzZXRDb2xsYXRvcgoJICovCiAgICBwdWJsaWMgUnVsZUJhc2VkQ29sbGF0b3IgZ2V0Q29sbGF0b3IoKSAKICAgIHsKICAgICAgICByZXR1cm4gbV9jb2xsYXRvcl87CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcGF0dGVybiBmb3Igd2hpY2ggU3RyaW5nU2VhcmNoIGlzIHNlYXJjaGluZyBmb3IuCiAgICAgKiBAcmV0dXJuIHRoZSBwYXR0ZXJuIHNlYXJjaGVkIGZvcgogICAgICovCiAgICBwdWJsaWMgU3RyaW5nIGdldFBhdHRlcm4oKSAKICAgIHsKICAgICAgICByZXR1cm4gbV9wYXR0ZXJuXy50YXJnZXRUZXh0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgaW5kZXggaW4gdGhlIHRhcmdldCB0ZXh0IHdoZXJlIHRoZSBpdGVyYXRvciBpcyBjdXJyZW50bHkgCiAgICAgKiBwb3NpdGlvbmVkIGF0LiAKICAgICAqIElmIHRoZSBpdGVyYXRpb24gaGFzIGdvbmUgcGFzdCB0aGUgZW5kIG9mIHRoZSB0YXJnZXQgdGV4dCBvciBwYXN0IAogICAgICogdGhlIGJlZ2lubmluZyBmb3IgYSBiYWNrd2FyZHMgc2VhcmNoLCB7QGxpbmsgI0RPTkV9IGlzIHJldHVybmVkLgogICAgICogQHJldHVybiBpbmRleCBpbiB0aGUgdGFyZ2V0IHRleHQgd2hlcmUgdGhlIGl0ZXJhdG9yIGlzIGN1cnJlbnRseSAKICAgICAqICAgICAgICAgcG9zaXRpb25lZCBhdAogICAgICogQGRyYWZ0IHJlbGVhc2UgMi4yCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXgoKSAKICAgIHsKICAgICAgICBpbnQgcmVzdWx0ID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CiAgICAgICAgaWYgKGlzT3V0T2ZCb3VuZHMobV90ZXh0QmVnaW5PZmZzZXRfLCBtX3RleHRMaW1pdE9mZnNldF8sIHJlc3VsdCkpIHsKICAgICAgICAgICAgcmV0dXJuIERPTkU7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIGNhbm9uaWNhbCBtYXRjaGVzIChvcHRpb24gMSwgYXMgZGVzY3JpYmVkIGluIHRoZSAKICAgICAqIGNsYXNzIGRvY3VtZW50YXRpb24pIGlzIHNldC4KICAgICAqIFNlZSBzZXRDYW5vbmljYWwoYm9vbGVhbikgZm9yIG1vcmUgaW5mb3JtYXRpb24uCiAgICAgKiBAc2VlICNzZXRDYW5vbmljYWwKICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBjYW5vbmljYWwgbWF0Y2hlcyBpcyBzZXQsIGZhbHNlIG90aGVyd2lzZQogICAgICogQGRyYWZ0IHJlbGVhc2UgMi4yCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGlzQ2Fub25pY2FsKCkgCiAgICB7CiAgICAgICAgcmV0dXJuIG1faXNDYW5vbmljYWxNYXRjaF87CiAgICB9CiAgICAKICAgIC8vIHB1YmxpYyBzZXR0ZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAKICAgIC8qKgogICAgICogPHA+CiAgICAgKiBTZXRzIHRoZSBzdHJlbmd0aCBwcm9wZXJ0eSBvZiB0aGUgUnVsZUJhc2VkQ29sbGF0b3IgdXNlZCBmb3Igc2VhcmNoaW5nLgogICAgICogU2VlIHRoZSBDb2xsYXRvciBkb2N1bWVudGF0aW9uIGZvciBhIGRlc2NyaXB0aW9uIG9mIHRoZSBzdHJlbmd0aHMuCiAgICAgKiA8L3A+CiAgICAgKiBAZGVwcmVjYXRlZCBzaW5jZSByZWxlYXNlIDIuMiwgdXNlciB3aG8gd291bGQgbGlrZSB0byBtb2RpZnkgdGhlIAogICAgICogCQkgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IsIHNob3VsZCByZXRyaWV2ZSB0aGUgUnVsZUJhc2VkQ29sbGF0b3IgCiAgICAgKiAgICAgICAgICAgICB2aWEgdGhlIEFQSSBnZXRDb2xsYXRvcigpLCBhbmQgdXNlIHRoZSBDb2xsYXRvciBBUElzIHRvIAogICAgICogCQkgICAgICAgbW9kaWZ5IHRoZSBzdHJlbmd0aC4gQWZ0ZXIgd2hpY2ggU3RyaW5nU2VhcmNoLnJlc2V0KCkgCiAgICAgKiAgICAgICAgICAgICBvciBTdHJpbmdTZWFyY2guc2V0Q29sbGF0b3IoUnVsZUJhc2VkQ29sbGF0b3IpIHNob3VsZCBiZQogICAgICogICAgICAgICAgICAgY2FsbGVkIHRvIHVwZGF0ZSBTdHJpbmdTZWFyY2guCiAgICAgKiBAc2VlIENvbGxhdG9yCiAgICAgKiBAc2VlIENvbGxhdG9yI1BSSU1BUlkKICAgICAqIEBzZWUgQ29sbGF0b3IjU0VDT05EQVJZCiAgICAgKiBAc2VlIENvbGxhdG9yI1RFUlRJQVJZCiAgICAgKiBAc2VlIENvbGxhdG9yI1FVQVRFUk5BUlkKICAgICAqIEBzZWUgQ29sbGF0b3IjSURFTlRJQ0FMCiAgICAgKiBAc2VlICNzZXRDb2xsYXRvcgogICAgICogQHNlZSAjZ2V0Q29sbGF0b3IKICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0U3RyZW5ndGgoaW50IG5ld1N0cmVuZ3RoKSAKICAgIHsKICAgICAgICAvLyBEdWUgdG8gYSBidWcgKD8pIGluIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciwgd2UgbXVzdCBzZXQgdGhlCiAgICAgICAgLy8gY29sbGF0b3IncyBzdHJlbmd0aCBhcyB3ZWxsLCBzaW5jZSB0aGUgaXRlcmF0b3IgaXMgZ29pbmcgdG8KICAgICAgICAvLyBtYXNrIG91dCB0aGUgcG9ydGlvbnMgb2YgdGhlIGNvbGxhdGlvbiBlbGVtZW50IHRoYXQgYXJlIG5vdAogICAgICAgIC8vIHJlbGV2YW50IGZvciB0aGUgY29sbGF0b3IncyBjdXJyZW50IHN0cmVuZ3RoIHNldHRpbmcKICAgICAgICAvLyBOb3RlIHRoYXQgdGhpcyBtYWtlcyBpdCBpbXBvc3NpYmxlIHRvIHNoYXJlIGEgQ29sbGF0b3IgYW1vbmcKICAgICAgICAvLyBtdWx0aXBsZSBTdHJpbmdTZWFyY2ggb2JqZWN0cyBpZiB5b3UgYWRqdXN0IFN0cmVuZ3RoIHNldHRpbmdzLgogICAgICAgIG1fY29sbGF0b3JfLnNldFN0cmVuZ3RoKG5ld1N0cmVuZ3RoKTsKICAgICAgICBpbml0aWFsaXplKCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogPHA+CiAgICAgKiBTZXRzIHRoZSBSdWxlQmFzZWRDb2xsYXRvciB0byBiZSB1c2VkIGZvciBsYW5ndWFnZS1zcGVjaWZpYyBzZWFyY2hpbmcuCiAgICAgKiA8L3A+CiAgICAgKiA8cD4KICAgICAqIFRoaXMgbWV0aG9kIGNhdXNlcyBpbnRlcm5hbCBkYXRhIHN1Y2ggYXMgQm95ZXItTW9vcmUgc2hpZnQgdGFibGVzCiAgICAgKiB0byBiZSByZWNhbGN1bGF0ZWQsIGJ1dCB0aGUgaXRlcmF0b3IncyBwb3NpdGlvbiBpcyB1bmNoYW5nZWQuCiAgICAgKiA8L3A+CiAgICAgKiBAcGFyYW0gY29sbGF0b3IgdG8gdXNlIGZvciB0aGlzIFN0cmluZ1NlYXJjaAogICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gdGhyb3duIHdoZW4gY29sbGF0b3IgaXMgbnVsbAogICAgICogQHNlZSAjZ2V0Q29sbGF0b3IKICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0Q29sbGF0b3IoUnVsZUJhc2VkQ29sbGF0b3IgY29sbGF0b3IpIAogICAgewogICAgCWlmIChjb2xsYXRvciA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkNvbGxhdG9yIGNhbiBub3QgYmUgbnVsbCIpOwogICAgICAgIH0KICAgICAgICBtX2NvbGxhdG9yXyA9IGNvbGxhdG9yOwogICAgICAgIG1fY2VNYXNrXyA9IGdldE1hc2sobV9jb2xsYXRvcl8uZ2V0U3RyZW5ndGgoKSk7CiAgICAgICAgLy8gaWYgc3RhdHVzIGlzIGEgZmFpbHVyZSwgdWNvbF9nZXRBdHRyaWJ1dGUgcmV0dXJucyBVQ09MX0RFRkFVTFQKICAgICAgICBpbml0aWFsaXplKCk7CiAgICAgICAgbV9jb2xFSXRlcl8uc2V0Q29sbGF0b3IobV9jb2xsYXRvcl8pOwogICAgICAgIG1fdXRpbENvbEVJdGVyXy5zZXRDb2xsYXRvcihtX2NvbGxhdG9yXyk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogPHA+CiAgICAgKiBTZXQgdGhlIHBhdHRlcm4gdG8gc2VhcmNoIGZvci4gIAogICAgICogPC9wPgogICAgICogPHA+CiAgICAgKiBUaGlzIG1ldGhvZCBjYXVzZXMgaW50ZXJuYWwgZGF0YSBzdWNoIGFzIEJveWVyLU1vb3JlIHNoaWZ0IHRhYmxlcwogICAgICogdG8gYmUgcmVjYWxjdWxhdGVkLCBidXQgdGhlIGl0ZXJhdG9yJ3MgcG9zaXRpb24gaXMgdW5jaGFuZ2VkLgogICAgICogPC9wPgogICAgICogQHBhcmFtIHBhdHRlcm4gZm9yIHNlYXJjaGluZwogICAgICogQHNlZSAjZ2V0UGF0dGVybgogICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gdGhyb3duIGlmIHBhdHRlcm4gaXMgbnVsbCBvciBvZgogICAgICogCQkJICBsZW5ndGggMAogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRQYXR0ZXJuKFN0cmluZyBwYXR0ZXJuKSAKICAgIHsKICAgIAlpZiAocGF0dGVybiA9PSBudWxsIHx8IHBhdHRlcm4ubGVuZ3RoKCkgPD0gMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAJCSJQYXR0ZXJuIHRvIHNlYXJjaCBmb3IgY2FuIG5vdCBiZSBudWxsIG9yIG9mIGxlbmd0aCAwIik7CiAgICAgICAgfQogICAgICAgIG1fcGF0dGVybl8udGFyZ2V0VGV4dCA9IHBhdHRlcm47CiAgICAgICAgaW5pdGlhbGl6ZSgpOwogICAgfQogICAgCiAgICAvKioKIAkgKiBTZXQgdGhlIHRhcmdldCB0ZXh0IHRvIGJlIHNlYXJjaGVkLiBUZXh0IGl0ZXJhdGlvbiB3aWxsIGhlbmNlIGJlZ2luIGF0IAogICAgICogdGhlIHN0YXJ0IG9mIHRoZSB0ZXh0IHN0cmluZy4gVGhpcyBtZXRob2QgaXMgdXNlZnVsIGlmIHlvdSB3YW50IHRvIAogICAgICogcmUtdXNlIGFuIGl0ZXJhdG9yIHRvIHNlYXJjaCB3aXRoaW4gYSBkaWZmZXJlbnQgYm9keSBvZiB0ZXh0LgogICAgICogQHBhcmFtIHRleHQgbmV3IHRleHQgaXRlcmF0b3IgdG8gbG9vayBmb3IgbWF0Y2gsIAogICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gdGhyb3duIHdoZW4gdGV4dCBpcyBudWxsIG9yIGhhcwogICAgICogICAgICAgICAgICAwIGxlbmd0aAogICAgICogQHNlZSAjZ2V0VGFyZ2V0CgkgKiBAZHJhZnQgcmVsZWFzZSAyLjIKCSAqLwoJcHVibGljIHZvaWQgc2V0VGFyZ2V0KENoYXJhY3Rlckl0ZXJhdG9yIHRleHQpCgl7CgkJc3VwZXIuc2V0VGFyZ2V0KHRleHQpOwogICAgICAgIG1fdGV4dEJlZ2luT2Zmc2V0XyA9IHRhcmdldFRleHQuZ2V0QmVnaW5JbmRleCgpOwogICAgICAgIG1fdGV4dExpbWl0T2Zmc2V0XyA9IHRhcmdldFRleHQuZ2V0RW5kSW5kZXgoKTsKICAgICAgICBtX2NvbEVJdGVyXy5zZXRUZXh0KHRhcmdldFRleHQpOwoJfQogICAgCiAgICAvKioKCSAqIDxwPgogICAgICogU2V0cyB0aGUgcG9zaXRpb24gaW4gdGhlIHRhcmdldCB0ZXh0IHdoaWNoIHRoZSBuZXh0IHNlYXJjaCB3aWxsIHN0YXJ0IAogICAgICogZnJvbSB0byB0aGUgYXJndW1lbnQuIFRoaXMgbWV0aG9kIGNsZWFycyBhbGwgcHJldmlvdXMgc3RhdGVzLgogICAgICogPC9wPgogICAgICogPHA+CiAgICAgKiBUaGlzIG1ldGhvZCB0YWtlcyB0aGUgYXJndW1lbnQgcG9zaXRpb24gYW5kIHNldHMgdGhlIHBvc2l0aW9uIGluIHRoZSAKICAgICAqIHRhcmdldCB0ZXh0IGFjY29yZGluZ2x5LCB3aXRob3V0IGNoZWNraW5nIGlmIHBvc2l0aW9uIGlzIHBvaW50aW5nIHRvIGEgCiAgICAgKiB2YWxpZCBzdGFydGluZyBwb2ludCB0byBiZWdpbiBzZWFyY2hpbmcuCiAgICAgKiA8L3A+CiAgICAgKiA8cD4KICAgICAqIFNlYXJjaCBwb3NpdGlvbnMgdGhhdCBtYXkgcmVuZGVyIGluY29ycmVjdCByZXN1bHRzIGFyZSBoaWdobGlnaHRlZCBpbiAKICAgICAqIHRoZSBjbGFzcyBkb2N1bWVudGF0aW9uLgogICAgICogPC9wPgogICAgICogQHBhcmFtIHBvc2l0aW9uIGluZGV4IHRvIHN0YXJ0IG5leHQgc2VhcmNoIGZyb20uCiAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gdGhyb3duIGlmIGFyZ3VtZW50IHBvc2l0aW9uIGlzIG91dAogICAgICogICAgICAgICAgICBvZiB0aGUgdGFyZ2V0IHRleHQgcmFuZ2UuCiAgICAgKiBAc2VlICNnZXRJbmRleAogICAgICogQGRyYWZ0IHJlbGVhc2UgMi4yCgkgKi8KCXB1YmxpYyB2b2lkIHNldEluZGV4KGludCBwb3NpdGlvbikKCXsKCQlzdXBlci5zZXRJbmRleChwb3NpdGlvbik7CiAgICAgICAgbV9tYXRjaGVkSW5kZXhfID0gRE9ORTsKICAgICAgICBtX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldChwb3NpdGlvbik7Cgl9CgkKCS8qKgoJICogPHA+CiAgICAgKiBTZXQgdGhlIGNhbm9uaWNhbCBtYXRjaCBtb2RlLiBTZWUgY2xhc3MgZG9jdW1lbnRhdGlvbiBmb3IgZGV0YWlscy4KICAgICAqIFRoZSBkZWZhdWx0IHNldHRpbmcgZm9yIHRoaXMgcHJvcGVydHkgaXMgZmFsc2UuCiAgICAgKiA8L3A+CgkgKiBAcGFyYW0gYWxsb3dDYW5vbmljYWwgZmxhZyBpbmRpY2F0b3IgaWYgY2Fub25pY2FsIG1hdGNoZXMgYXJlIGFsbG93ZWQKICAgICAqIEBzZWUgI2lzQ2Fub25pY2FsCgkgKiBAZHJhZnQgcmVsZWFzZSAyLjIKCSAqLwoJcHVibGljIHZvaWQgc2V0Q2Fub25pY2FsKGJvb2xlYW4gYWxsb3dDYW5vbmljYWwpCgl7CgkJbV9pc0Nhbm9uaWNhbE1hdGNoXyA9IGFsbG93Q2Fub25pY2FsOwoJCWlmIChtX2lzQ2Fub25pY2FsTWF0Y2hfID09IHRydWUpIHsKCQkJaWYgKG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18gPT0gbnVsbCkgewoJCQkJbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXyA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKCQkJfQoJCQllbHNlIHsKCQkJCW1fY2Fub25pY2FsUHJlZml4QWNjZW50c18uZGVsZXRlKDAsIAoJCQkJCQkJCQkJCW1fY2Fub25pY2FsUHJlZml4QWNjZW50c18ubGVuZ3RoKCkpOwoJCQl9CgkJCWlmIChtX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfID09IG51bGwpIHsKCQkJCW1fY2Fub25pY2FsU3VmZml4QWNjZW50c18gPSBuZXcgU3RyaW5nQnVmZmVyKCk7CgkJCX0KCQkJZWxzZSB7CgkJCQltX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfLmRlbGV0ZSgwLCAKCQkJCQkJCQkJCQltX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfLmxlbmd0aCgpKTsKCQkJfQoJCX0KCX0KCQoJLy8gcHVibGljIG1pc2NlbGxhbmVvdXMgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJCgkvKiogCgkgKiA8cD4KICAgICAqIFJlc2V0cyB0aGUgc2VhcmNoIGl0ZXJhdGlvbi4gQWxsIHByb3BlcnRpZXMgd2lsbCBiZSByZXNldCB0byB0aGUgCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICogPC9wPgogICAgICogPHA+CiAgICAgKiBTZWFyY2ggd2lsbCBiZWdpbiBhdCB0aGUgc3RhcnQgb2YgdGhlIHRhcmdldCB0ZXh0IGlmIGEgZm9yd2FyZCBpdGVyYXRpb24gCiAgICAgKiBpcyBpbml0aWF0ZWQgYmVmb3JlIGEgYmFja3dhcmRzIGl0ZXJhdGlvbi4gT3RoZXJ3aXNlIGlmIGEgCiAgICAgKiBiYWNrd2FyZHMgaXRlcmF0aW9uIGlzIGluaXRpYXRlZCBiZWZvcmUgYSBmb3J3YXJkcyBpdGVyYXRpb24sIHRoZSBzZWFyY2ggCiAgICAgKiB3aWxsIGJlZ2luIGF0IHRoZSBlbmQgb2YgdGhlIHRhcmdldCB0ZXh0LgogICAgICogPC9wPgogICAgICogPHA+CiAgICAgKiBDYW5vbmljYWwgbWF0Y2ggb3B0aW9uIHdpbGwgYmUgcmVzZXQgdG8gZmFsc2UsIGllIGFuIGV4YWN0IG1hdGNoLgogICAgICogPC9wPgoJICogQGRyYWZ0IHJlbGVhc2UgMi4yCgkgKi8KCXB1YmxpYyB2b2lkIHJlc2V0KCkKCXsKCQkvLyByZXNldCBpcyBzZXR0aW5nIHRoZSBhdHRyaWJ1dGVzIHRoYXQgYXJlIGFscmVhZHkgaW4gc3RyaW5nIHNlYXJjaCwgCgkJLy8gaGVuY2UgYWxsIGF0dHJpYnV0ZXMgaW4gdGhlIGNvbGxhdG9yIHNob3VsZCBiZSByZXRyaWV2ZWQgd2l0aG91dCBhbnkgCgkJLy8gcHJvYmxlbXMKCQlzdXBlci5yZXNldCgpOwogICAgICAgIG1faXNDYW5vbmljYWxNYXRjaF8gPSBmYWxzZTsKICAgICAgICBtX2NlTWFza18gPSBnZXRNYXNrKG1fY29sbGF0b3JfLmdldFN0cmVuZ3RoKCkpOwogICAgICAgIC8vIGlmIHN0YXR1cyBpcyBhIGZhaWx1cmUsIHVjb2xfZ2V0QXR0cmlidXRlIHJldHVybnMgVUNPTF9ERUZBVUxUCiAgICAgICAgaW5pdGlhbGl6ZSgpOwogICAgICAgIG1fY29sRUl0ZXJfLnNldENvbGxhdG9yKG1fY29sbGF0b3JfKTsKICAgICAgICBtX2NvbEVJdGVyXy5yZXNldCgpOwogICAgICAgIG1fdXRpbENvbEVJdGVyXy5zZXRDb2xsYXRvcihtX2NvbGxhdG9yXyk7Cgl9CgogICAgLy8gcHJvdGVjdGVkIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIAogICAgLyoqCiAgICAgKiA8cD4KICAgICAqIENvbmNyZXRlIG1ldGhvZCB0byBwcm92aWRlIHRoZSBtZWNoYW5pc20gCiAgICAgKiBmb3IgZmluZGluZyB0aGUgbmV4dCA8Yj5mb3J3YXJkczwvYj4gbWF0Y2ggaW4gdGhlIHRhcmdldCB0ZXh0LgogICAgICogU2VlIHN1cGVyIGNsYXNzIGRvY3VtZW50YXRpb24gZm9yIGl0cyB1c2UuCiAgICAgKiA8L3A+ICAKICAgICAqIEBwYXJhbSBzdGFydCBpbmRleCBpbiB0aGUgdGFyZ2V0IHRleHQgYXQgd2hpY2ggdGhlIGZvcndhcmRzIHNlYXJjaCAKICAgICAqICAgICAgICBzaG91bGQgYmVnaW4uCiAgICAgKiBAcmV0dXJuIHRoZSBzdGFydGluZyBpbmRleCBvZiB0aGUgbmV4dCBmb3J3YXJkcyBtYXRjaCBpZiBmb3VuZCwgRE9ORSAKICAgICAqICAgICAgICAgb3RoZXJ3aXNlCiAgICAgKiBAc2VlICNoYW5kbGVQcmV2aW91cyhpbnQpCiAgICAgKiBAc2VlICNET05FCiAgICAgKi8KICAgIHByb3RlY3RlZCBpbnQgaGFuZGxlTmV4dChpbnQgc3RhcnQpCiAgICB7CiAgICAJaWYgKG1fcGF0dGVybl8ubV9DRUxlbmd0aF8gPT0gMCkgewogICAgICAgICAgICBtYXRjaExlbmd0aCA9IDA7CiAgICAgICAgICAgIGlmIChtX21hdGNoZWRJbmRleF8gPT0gRE9ORSAmJiBzdGFydCA9PSBtX3RleHRCZWdpbk9mZnNldF8pIHsKICAgICAgICAgICAgICAgIG1fbWF0Y2hlZEluZGV4XyA9IHN0YXJ0OwogICAgICAgICAgICAgICAgcmV0dXJuIG1fbWF0Y2hlZEluZGV4XzsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgIAkJdGFyZ2V0VGV4dC5zZXRJbmRleChzdGFydCk7CgkgICAgICAgIGNoYXIgY2ggPSB0YXJnZXRUZXh0LmN1cnJlbnQoKTsKCSAgICAgICAgLy8gY2ggY2FuIG5ldmVyIGJlIGRvbmUsIGl0IGlzIGhhbmRsZWQgYnkgbmV4dCgpCgkgICAgICAgIGNoYXIgY2gyID0gdGFyZ2V0VGV4dC5uZXh0KCk7CgkgICAgICAgIGlmIChjaDIgPT0gQ2hhcmFjdGVySXRlcmF0b3IuRE9ORSkgewoJICAgICAgICAgICAgbV9tYXRjaGVkSW5kZXhfID0gRE9ORTsJCgkgICAgICAgIH0KCSAgICAgICAgZWxzZSB7CgkgICAgICAgICAgICBtX21hdGNoZWRJbmRleF8gPSB0YXJnZXRUZXh0LmdldEluZGV4KCk7CgkgICAgICAgIH0KCSAgICAgICAgaWYgKFVURjE2LmlzTGVhZFN1cnJvZ2F0ZShjaCkgJiYgVVRGMTYuaXNUcmFpbFN1cnJvZ2F0ZShjaDIpKSB7CgkgICAgICAgICAgICB0YXJnZXRUZXh0Lm5leHQoKTsKCSAgICAgICAgICAgIG1fbWF0Y2hlZEluZGV4XyA9IHRhcmdldFRleHQuZ2V0SW5kZXgoKTsKCSAgICAgICAgfQoJICAgIH0KCSAgICBlbHNlIHsKCSAgICAJaWYgKG1hdGNoTGVuZ3RoICE9IDApIHsKCQkgICAgCXN0YXJ0ICs9IG1hdGNoTGVuZ3RoOwoJCSAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgLy8gd2UgbXVzdCBoYXZlIHJldmVyc2VkIGRpcmVjdGlvbiBhZnRlciB3ZSByZWFjaGVkIHRoZSBzdGFydAogICAgICAgICAgICAgICAgLy8gb2YgdGhlIHRhcmdldCB0ZXh0CiAgICAgICAgICAgICAgICAvLyBzZWUgU2VhcmNoSXRlcmF0b3IgbmV4dCgpLCBpdCBjaGVja3MgdGhlIGJvdW5kcyBhbmQgcmV0dXJucwogICAgICAgICAgICAgICAgLy8gaWYgaXQgZXhjZWVkcyB0aGUgcmFuZ2UuIEl0IGRvZXMgbm90IGFsbG93IHNldHRpbmcgb2YKICAgICAgICAgICAgICAgIC8vIG1fbWF0Y2hlZEluZGV4CiAgICAgICAgICAgICAgICBtX21hdGNoZWRJbmRleF8gPSBET05FOwogICAgICAgICAgICB9CiAgICAKCSAgICAgICAgLy8gc3RhdHVzIGNoZWNrZWQgYmVsb3cKCSAgICAgICAgaWYgKG1faXNDYW5vbmljYWxNYXRjaF8pIHsKCSAgICAgICAgICAgIC8vIGNhbid0IHVzZSBleGFjdCBoZXJlIHNpbmNlIGV4dHJhIGFjY2VudHMgYXJlIGFsbG93ZWQuCgkgICAgICAgICAgICBoYW5kbGVOZXh0Q2Fub25pY2FsKHN0YXJ0KTsKCSAgICAgICAgfQoJICAgICAgICBlbHNlIHsKCSAgICAgICAgICAgIGhhbmRsZU5leHRFeGFjdChzdGFydCk7CgkgICAgICAgIH0KCSAgICB9CiAgICAgICAgaWYgKG1fbWF0Y2hlZEluZGV4XyA9PSBET05FKSB7CiAgICAgICAgICAgIHRhcmdldFRleHQuc2V0SW5kZXgobV90ZXh0TGltaXRPZmZzZXRfKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIHRhcmdldFRleHQuc2V0SW5kZXgobV9tYXRjaGVkSW5kZXhfKTsKICAgICAgICB9CiAgICAJcmV0dXJuIG1fbWF0Y2hlZEluZGV4XzsKICAgIH0KICAgIAogICAgLyoqCgkgKiA8cD4KICAgICAqIENvbmNyZXRlIG1ldGhvZCB0byBwcm92aWRlIHRoZSBtZWNoYW5pc20gCiAgICAgKiBmb3IgZmluZGluZyB0aGUgbmV4dCA8Yj5iYWNrd2FyZHM8L2I+IG1hdGNoIGluIHRoZSB0YXJnZXQgdGV4dC4KICAgICAqIFNlZSBzdXBlciBjbGFzcyBkb2N1bWVudGF0aW9uIGZvciBpdHMgdXNlLgogICAgICogPC9wPiAgCiAgICAgKiBAcGFyYW0gc3RhcnQgaW5kZXggaW4gdGhlIHRhcmdldCB0ZXh0IGF0IHdoaWNoIHRoZSBiYWNrd2FyZHMgc2VhcmNoIAogICAgICogICAgICAgIHNob3VsZCBiZWdpbi4KICAgICAqIEByZXR1cm4gdGhlIHN0YXJ0aW5nIGluZGV4IG9mIHRoZSBuZXh0IGJhY2t3YXJkcyBtYXRjaCBpZiBmb3VuZCwgRE9ORSAKICAgICAqICAgICAgICAgb3RoZXJ3aXNlCiAgICAgKiBAc2VlICNoYW5kbGVOZXh0KGludCkKICAgICAqIEBzZWUgI0RPTkUKCSAqLwogICAgcHJvdGVjdGVkIGludCBoYW5kbGVQcmV2aW91cyhpbnQgc3RhcnQpCiAgICB7CiAgICAJaWYgKG1fcGF0dGVybl8ubV9DRUxlbmd0aF8gPT0gMCkgewogICAgICAgICAgICBtYXRjaExlbmd0aCA9IDA7CgkgICAgICAgIC8vIHN0YXJ0IGNhbiBuZXZlciBiZSBET05FIG9yIDAsIGl0IGlzIGhhbmRsZWQgaW4gcHJldmlvdXMKICAgICAgICAgICAgdGFyZ2V0VGV4dC5zZXRJbmRleChzdGFydCk7CiAgICAgICAgICAgIGNoYXIgY2ggPSB0YXJnZXRUZXh0LnByZXZpb3VzKCk7CiAgICAgICAgICAgIGlmIChjaCA9PSBDaGFyYWN0ZXJJdGVyYXRvci5ET05FKSB7CiAgICAgICAgICAgIAltX21hdGNoZWRJbmRleF8gPSBET05FOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAJbV9tYXRjaGVkSW5kZXhfID0gdGFyZ2V0VGV4dC5nZXRJbmRleCgpOwoJICAgICAgICAgICAgaWYgKFVURjE2LmlzVHJhaWxTdXJyb2dhdGUoY2gpKSB7CgkgICAgICAgICAgICAJaWYgKFVURjE2LmlzTGVhZFN1cnJvZ2F0ZSh0YXJnZXRUZXh0LnByZXZpb3VzKCkpKSB7CgkgICAgICAgICAgICAgICAgICAgIG1fbWF0Y2hlZEluZGV4XyA9IHRhcmdldFRleHQuZ2V0SW5kZXgoKTsKCSAgICAgICAgICAgIAl9CgkgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gICAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGlmIChtYXRjaExlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgICAgICAvLyB3ZSBtdXN0IGhhdmUgcmV2ZXJzZWQgZGlyZWN0aW9uIGFmdGVyIHdlIHJlYWNoZWQgdGhlIGVuZAogICAgICAgICAgICAgICAgLy8gb2YgdGhlIHRhcmdldCB0ZXh0CiAgICAgICAgICAgICAgICAvLyBzZWUgU2VhcmNoSXRlcmF0b3IgbmV4dCgpLCBpdCBjaGVja3MgdGhlIGJvdW5kcyBhbmQgcmV0dXJucwogICAgICAgICAgICAgICAgLy8gaWYgaXQgZXhjZWVkcyB0aGUgcmFuZ2UuIEl0IGRvZXMgbm90IGFsbG93IHNldHRpbmcgb2YKICAgICAgICAgICAgICAgIC8vIG1fbWF0Y2hlZEluZGV4CiAgICAgICAgICAgICAgICBtX21hdGNoZWRJbmRleF8gPSBET05FOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChtX2lzQ2Fub25pY2FsTWF0Y2hfKSB7CiAgICAgICAgICAgICAgICAvLyBjYW4ndCB1c2UgZXhhY3QgaGVyZSBzaW5jZSBleHRyYSBhY2NlbnRzIGFyZSBhbGxvd2VkLgogICAgICAgICAgICAgICAgaGFuZGxlUHJldmlvdXNDYW5vbmljYWwoc3RhcnQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgaGFuZGxlUHJldmlvdXNFeGFjdChzdGFydCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChtX21hdGNoZWRJbmRleF8gPT0gRE9ORSkgewogICAgICAgICAgICB0YXJnZXRUZXh0LnNldEluZGV4KG1fdGV4dEJlZ2luT2Zmc2V0Xyk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICB0YXJnZXRUZXh0LnNldEluZGV4KG1fbWF0Y2hlZEluZGV4Xyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtX21hdGNoZWRJbmRleF87CiAgICB9CgogICAgLy8gcHJpdmF0ZSBzdGF0aWMgaW5uZXIgY2xhc3NlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAKICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFBhdHRlcm4gCiAgICB7CiAgICAJLy8gcHJvdGVjdGVkIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIAkKICAgIAkvKioKICAgIAkgKiBQYXR0ZXJuIHN0cmluZwogICAgCSAqLwogICAgCXByb3RlY3RlZCBTdHJpbmcgdGFyZ2V0VGV4dDsKICAgICAgICAvKioKICAgICAgICAgKiBBcnJheSBjb250YWluaW5nIHRoZSBjb2xsYXRpb24gZWxlbWVudHMgb2YgdGFyZ2V0VGV4dAogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBpbnQgbV9DRV9bXTsKICAgICAgICAvKioKICAgICAgICAgKiBOdW1iZXIgb2YgY29sbGF0aW9uIGVsZW1lbnRzIGluIG1fQ0VfCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIGludCBtX0NFTGVuZ3RoXzsgCiAgICAgICAgLyoqCiAgICAgICAgICogRmxhZyBpbmRpY2F0b3IgaWYgdGFyZ2V0VGV4dCBzdGFydHMgd2l0aCBhbiBhY2NlbnQKICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiBtX2hhc1ByZWZpeEFjY2VudHNfOwogICAgICAgIC8qKgogICAgICAgICAqIEZsYWcgaW5kaWNhdG9yIGlmIHRhcmdldFRleHQgZW5kcyB3aXRoIGFuIGFjY2VudAogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBib29sZWFuIG1faGFzU3VmZml4QWNjZW50c187CiAgICAgICAgLyoqCiAgICAgICAgICogRGVmYXVsdCBudW1iZXIgb2YgY2hhcmFjdGVycyB0byBzaGlmdCBmb3IgQm95ZXIgTW9vcmUKICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgaW50IG1fZGVmYXVsdFNoaWZ0U2l6ZV87CiAgICAgICAgLyoqCiAgICAgICAgICogTnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gc2hpZnQgZm9yIEJveWVyIE1vb3JlLCBkZXBlbmRpbmcgb24gdGhlCiAgICAgICAgICogc291cmNlIHRleHQgdG8gc2VhcmNoCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIGNoYXIgbV9zaGlmdF9bXTsKICAgICAgICAvKioKICAgICAgICAgKiBOdW1iZXIgb2YgY2hhcmFjdGVycyB0byBzaGlmdCBiYWNrd2FyZHMgZm9yIEJveWVyIE1vb3JlLCBkZXBlbmRpbmcgCiAgICAgICAgICogb24gdGhlIHNvdXJjZSB0ZXh0IHRvIHNlYXJjaAogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBjaGFyIG1fYmFja1NoaWZ0X1tdOwogICAgICAgIAogICAgICAgIC8vIHByb3RlY3RlZCBjb25zdHJ1Y3RvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgCiAgICAgICAgLyoqCiAgICAgICAgICogRW1wdHkgY29uc3RydWN0b3IgCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIFBhdHRlcm4oU3RyaW5nIHBhdHRlcm4pIAogICAgICAgIHsKICAgICAgICAJdGFyZ2V0VGV4dCA9IHBhdHRlcm47CiAgICAgICAgCW1fQ0VfID0gbmV3IGludFtJTklUSUFMX0FSUkFZX1NJWkVfXTsJCiAgICAgICAgCW1fQ0VMZW5ndGhfID0gMDsKICAgICAgICAJbV9oYXNQcmVmaXhBY2NlbnRzXyA9IGZhbHNlOwogICAgICAgIAltX2hhc1N1ZmZpeEFjY2VudHNfID0gZmFsc2U7CiAgICAgICAgCW1fZGVmYXVsdFNoaWZ0U2l6ZV8gPSAxOwkJCiAgICAgICAgCW1fc2hpZnRfID0gbmV3IGNoYXJbTUFYX1RBQkxFX1NJWkVfXTsKICAgICAgICAJbV9iYWNrU2hpZnRfID0gbmV3IGNoYXJbTUFYX1RBQkxFX1NJWkVfXTsKICAgICAgICB9CiAgICB9OwoKCiAgICAvLyBwcml2YXRlIGRhdGEgbWVtYmVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIAogICAgLyoqCiAgICAgKiB0YXJnZXQgdGV4dCBiZWdpbiBvZmZzZXQuIEVhY2ggdGFyZ2V0VGV4dCBoYXMgYSB2YWxpZCBjb250aWd1b3VzIHJlZ2lvbiAKICAgICAqIHRvIGl0ZXJhdGUgYW5kIHRoaXMgZGF0YSBtZW1iZXIgaXMgdGhlIG9mZnNldCB0byB0aGUgZmlyc3Qgc3VjaAogICAgICogY2hhcmFjdGVyIGluIHRoZSByZWdpb24uCiAgICAgKi8KICAgIHByaXZhdGUgaW50IG1fdGV4dEJlZ2luT2Zmc2V0XzsKICAgIC8qKgogICAgICogdGFyZ2V0IHRleHQgbGltaXQgb2Zmc2V0LiBFYWNoIHRhcmdldFRleHQgaGFzIGEgdmFsaWQgY29udGlndW91cyByZWdpb24gCiAgICAgKiB0byBpdGVyYXRlIGFuZCB0aGlzIGRhdGEgbWVtYmVyIGlzIHRoZSBvZmZzZXQgdG8gMSBhZnRlciB0aGUgbGFzdCBzdWNoCiAgICAgKiBjaGFyYWN0ZXIgaW4gdGhlIHJlZ2lvbi4KICAgICAqLwogICAgcHJpdmF0ZSBpbnQgbV90ZXh0TGltaXRPZmZzZXRfOwogICAgLyoqCiAgICAgKiBVcG9uIGNvbXBsZXRpb24gb2YgYSBzZWFyY2gsIG1fbWF0Y2hJbmRleF8gd2lsbCBzdG9yZSBzdGFydGluZyBvZmZzZXQgaW4KICAgICAqIG1fdGV4dCBmb3IgdGhlIG1hdGNoLiBUaGUgVmFsdWUgRE9ORSBpcyB0aGUgZGVmYXVsdCB2YWx1ZS4gCiAgICAgKiBJZiB3ZSBhcmUgbm90IGF0IHRoZSBzdGFydCBvZiB0aGUgdGV4dCBvciB0aGUgZW5kIG9mIHRoZSB0ZXh0IGFuZCAKICAgICAqIG1fbWF0Y2hlZEluZGV4XyBpcyBET05FIGl0IG1lYW5zIHRoYXQgd2UgY2FuIGZpbmQgYW55IG1vcmUgbWF0Y2hlcyBpbiAKICAgICAqIHRoYXQgcGFydGljdWxhciBkaXJlY3Rpb24KICAgICAqLwogICAgcHJpdmF0ZSBpbnQgbV9tYXRjaGVkSW5kZXhfOyAKICAgIC8qKgogICAgICogQ3VycmVudCBwYXR0ZXJuIHRvIHNlYXJjaCBmb3IKICAgICAqLwogICAgcHJpdmF0ZSBQYXR0ZXJuIG1fcGF0dGVybl87CiAgICAvKioKICAgICAqIENvbGxhdG9yIHdob3NlIHJ1bGVzIGFyZSB1c2VkIHRvIHBlcmZvcm0gdGhlIHNlYXJjaAogICAgICovCiAgICBwcml2YXRlIFJ1bGVCYXNlZENvbGxhdG9yIG1fY29sbGF0b3JfOwogICAgLyoqIAogICAgICogVGhlIGNvbGxhdGlvbiBlbGVtZW50IGl0ZXJhdG9yIGZvciB0aGUgdGV4dCBzb3VyY2UuCiAgICAgKi8KICAgIHByaXZhdGUgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIG1fY29sRUl0ZXJfOwogICAgLyoqIAogICAgICogVXRpbGl0eSBjb2xsYXRpb24gZWxlbWVudCwgdXNlZCB0aHJvdWdob3V0IHByb2dyYW0gZm9yIHRlbXBvcmFyeSAKICAgICAqIGl0ZXJhdGlvbi4KICAgICAqLwogICAgcHJpdmF0ZSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgbV91dGlsQ29sRUl0ZXJfOwogICAgLyoqCiAgICAgKiBUaGUgbWFzayB1c2VkIG9uIHRoZSBjb2xsYXRpb24gZWxlbWVudHMgdG8gcmV0cmlldmUgdGhlIHZhbGlkIHN0cmVuZ3RoCiAgICAgKiB3ZWlnaHQgCiAgICAgKi8KICAgIHByaXZhdGUgaW50IG1fY2VNYXNrXzsKICAgIC8qKgogICAgICogQnVmZmVyIHN0b3JpbmcgYWNjZW50cyBkdXJpbmcgYSBjYW5vbmljYWwgc2VhcmNoCiAgICAgKi8KICAgIHByaXZhdGUgU3RyaW5nQnVmZmVyIG1fY2Fub25pY2FsUHJlZml4QWNjZW50c187CiAgICAvKioKICAgICAqIEJ1ZmZlciBzdG9yaW5nIGFjY2VudHMgZHVyaW5nIGEgY2Fub25pY2FsIHNlYXJjaAogICAgICovCiAgICBwcml2YXRlIFN0cmluZ0J1ZmZlciBtX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfOwogICAgLyoqCiAgICAgKiBGbGFnIHRvIGluZGljYXRlIGlmIGNhbm9uaWNhbCBzZWFyY2ggaXMgdG8gYmUgZG9uZS4KICAgICAqIEUuZyBsb29raW5nIGZvciAiYVx1MDMwMCIgaW4gImFcdTAzMThcdTAzMDAiIHdpbGwgeWllbGQgdGhlIG1hdGNoIGF0IDAuCiAgICAgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBtX2lzQ2Fub25pY2FsTWF0Y2hfOwogICAgLyoqCiAgICAgKiBTaXplIG9mIHRoZSBzaGlmdCB0YWJsZXMKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9UQUJMRV9TSVpFXyA9IDI1NzsgCiAgICAvKioKICAgICAqIEluaXRpYWwgYXJyYXkgc2l6ZQogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5JVElBTF9BUlJBWV9TSVpFXyA9IDI1NjsKICAgIC8qKgogICAgICogVXRpbGl0eSBtYXNrCiAgICAgKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTRUNPTkRfTEFTVF9CWVRFX1NISUZUXyA9IDg7CgkvKioKICAgICAqIFV0aWxpdHkgbWFzawogICAgICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTEFTVF9CWVRFX01BU0tfID0gMHhmZjsKCS8qKgoJICogVXRpbGl0eSBidWZmZXIgZm9yIHJldHVybiB2YWx1ZXMgYW5kIHRlbXBvcmFyeSBzdG9yYWdlCgkgKi8KCXByaXZhdGUgaW50IG1fdXRpbEJ1ZmZlcl9bXSA9IG5ldyBpbnRbMl07CgoJLy8gcHJpdmF0ZSBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvKioKICAgICAqIEhhc2ggYSBjb2xsYXRpb24gZWxlbWVudCBmcm9tIGl0cyBmdWxsIHNpemUgKDMyIGJpdHMpIGRvd24gaW50byBhCiAgICAgKiB2YWx1ZSB0aGF0IGNhbiBiZSB1c2VkIGFzIGFuIGluZGV4IGludG8gdGhlIHNoaWZ0IHRhYmxlcy4gIFJpZ2h0CiAgICAgKiBub3cgd2UgZG8gYSBtb2R1bHVzIGJ5IHRoZSBzaXplIG9mIHRoZSBoYXNoIHRhYmxlLgogICAgICogQHBhcmFtIGNlIGNvbGxhdGlvbiBlbGVtZW50CgkgKiBAcmV0dXJuIGNvbGxhcHNlZCB2ZXJzaW9uIG9mIHRoZSBjb2xsYXRpb24gZWxlbWVudAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgaGFzaChpbnQgY2UpIAogICAgewogICAgICAgIC8vIHRoZSBvbGQgdmFsdWUgVUNPTF9QUklNQVJZT1JERVIoY2UpICUgTUFYX1RBQkxFX1NJWkVfIGRvZXMgbm90IHdvcmsKICAgIAkvLyB3ZWxsIHdpdGggdGhlIG5ldyBjb2xsYXRpb24gd2hlcmUgbW9zdCBvZiB0aGUgbGF0aW4gMSBjaGFyYWN0ZXJzCiAgICAJLy8gYXJlIG9mIHRoZSB2YWx1ZSB4eDAwMHh4eC4gdGhlaXIgaGFzaGVzIHdpbGwgbW9zdCBvZiB0aGUgdGltZSBiZSAwCiAgICAJLy8gdG8gYmUgZGlzY3Vzc2VkIG9uIHRoZSBoYXNoIGFsZ28uCiAgICAJcmV0dXJuIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5wcmltYXJ5T3JkZXIoY2UpICUgTUFYX1RBQkxFX1NJWkVfOwogICAgfQogICAgCiAgICAvKioKCSAqIEdldHMgdGhlIGZjZCB2YWx1ZSBmb3IgYSBjaGFyYWN0ZXIgYXQgdGhlIGFyZ3VtZW50IGluZGV4LgoJICogVGhpcyBtZXRob2QgdGFrZXMgaW50byBhY2NvdW50cyBvZiB0aGUgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzLgoJICogTm90ZSB0aGlzIG1ldGhvZCBjaGFuZ2VzIHRoZSBvZmZzZXQgaW4gdGhlIGNoYXJhY3RlciBpdGVyYXRvci4KCSAqIEBwYXJhbSBzdHIgVVRGMTYgc3RyaW5nIHdoZXJlIGNoYXJhY3RlciBmb3IgZmNkIHJldHJpZXZhbCByZXNpZGVzCgkgKiBAcGFyYW0gb2Zmc2V0IHBvc2l0aW9uIG9mIHRoZSBjaGFyYWN0ZXIgd2hvc2UgZmNkIGlzIHRvIGJlIHJldHJpZXZlZAoJICogQHJldHVybiBmY2QgdmFsdWUKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhciBnZXRGQ0QoQ2hhcmFjdGVySXRlcmF0b3Igc3RyLCBpbnQgb2Zmc2V0KQoJewoJICAgIHN0ci5zZXRJbmRleChvZmZzZXQpOwoJICAgIGNoYXIgY2ggPSBzdHIuY3VycmVudCgpOwoJICAgIGNoYXIgcmVzdWx0ID0gTm9ybWFsaXplckltcGwuZ2V0RkNEMTYoY2gpOwoJICAgIAoJICAgIGlmICgocmVzdWx0ICE9IDApICYmIChzdHIuZ2V0RW5kSW5kZXgoKSAhPSBvZmZzZXQgKyAxKSAmJiAKCSAgICAJVVRGMTYuaXNMZWFkU3Vycm9nYXRlKGNoKSkgewoJICAgICAgICBjaCA9IHN0ci5uZXh0KCk7CgkgICAgICAgIGlmIChVVEYxNi5pc1RyYWlsU3Vycm9nYXRlKGNoKSkgewoJICAgICAgICAgICAgcmVzdWx0ID0gTm9ybWFsaXplckltcGwuZ2V0RkNEMTZGcm9tU3Vycm9nYXRlUGFpcihyZXN1bHQsIGNoKTsKCSAgICAgICAgfSBlbHNlIHsKCSAgICAgICAgICAgIHJlc3VsdCA9IDA7CgkgICAgICAgIH0KCSAgICB9CgkgICAgcmV0dXJuIHJlc3VsdDsKCX0KCQoJLyoqCgkgKiBHZXRzIHRoZSBmY2QgdmFsdWUgZm9yIGEgY2hhcmFjdGVyIGF0IHRoZSBhcmd1bWVudCBpbmRleC4KCSAqIFRoaXMgbWV0aG9kIHRha2VzIGludG8gYWNjb3VudHMgb2YgdGhlIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVycy4KCSAqIEBwYXJhbSBzdHIgVVRGMTYgc3RyaW5nIHdoZXJlIGNoYXJhY3RlciBmb3IgZmNkIHJldHJpZXZhbCByZXNpZGVzCgkgKiBAcGFyYW0gb2Zmc2V0IHBvc2l0aW9uIG9mIHRoZSBjaGFyYWN0ZXIgd2hvc2UgZmNkIGlzIHRvIGJlIHJldHJpZXZlZAoJICogQHJldHVybiBmY2QgdmFsdWUKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhciBnZXRGQ0QoU3RyaW5nIHN0ciwgaW50IG9mZnNldCkKCXsKCSAgICBjaGFyIGNoID0gc3RyLmNoYXJBdChvZmZzZXQpOwoJICAgIGNoYXIgcmVzdWx0ID0gTm9ybWFsaXplckltcGwuZ2V0RkNEMTYoY2gpOwoJICAgIAoJICAgIGlmICgocmVzdWx0ICE9IDApICYmIChzdHIubGVuZ3RoKCkgIT0gb2Zmc2V0ICsgMSkgJiYgCgkgICAgCVVURjE2LmlzTGVhZFN1cnJvZ2F0ZShjaCkpIHsKCSAgICAgICAgY2ggPSBzdHIuY2hhckF0KG9mZnNldCArIDEpOwoJICAgICAgICBpZiAoVVRGMTYuaXNUcmFpbFN1cnJvZ2F0ZShjaCkpIHsKCSAgICAgICAgICAgIHJlc3VsdCA9IE5vcm1hbGl6ZXJJbXBsLmdldEZDRDE2RnJvbVN1cnJvZ2F0ZVBhaXIocmVzdWx0LCBjaCk7CgkgICAgICAgIH0gZWxzZSB7CgkgICAgICAgICAgICByZXN1bHQgPSAwOwoJICAgICAgICB9CgkgICAgfQoJICAgIHJldHVybiByZXN1bHQ7Cgl9CgkKCS8qKgoJKiBHZXR0aW5nIHRoZSBtb2RpZmllZCBjb2xsYXRpb24gZWxlbWVudHMgdGFraW5nIGludG8gYWNjb3VudCB0aGUgY29sbGF0aW9uIAoJKiBhdHRyaWJ1dGVzCgkqIEBwYXJhbSBjZSAKCSogQHJldHVybiB0aGUgbW9kaWZpZWQgY29sbGF0aW9uIGVsZW1lbnQKCSovCglwcml2YXRlIGZpbmFsIGludCBnZXRDRShpbnQgY2UpCgl7CgkgICAgLy8gbm90ZSBmb3IgdGVydGlhcnkgd2UgY2FuJ3QgdXNlIHRoZSBjb2xsYXRvci0+dGVydGlhcnlNYXNrLCB0aGF0CgkgICAgLy8gaXMgYSBwcmVwcm9jZXNzZWQgbWFzayB0aGF0IHRha2VzIGludG8gYWNjb3VudCBjYXNlIG9wdGlvbnMuIHNpbmNlCgkgICAgLy8gd2UgYXJlIG9ubHkgY29uY2VybmVkIHdpdGggZXhhY3QgbWF0Y2hlcywgd2UgZG9uJ3QgbmVlZCB0aGF0LgoJICAgIGNlICY9IG1fY2VNYXNrXzsKCSAgICAKCSAgICBpZiAobV9jb2xsYXRvcl8uaXNBbHRlcm5hdGVIYW5kbGluZ1NoaWZ0ZWQoKSkgewoJICAgICAgICAvLyBhbHRlcm5hdGUgaGFuZGxpbmcgaGVyZSwgc2luY2Ugb25seSB0aGUgMTYgbW9zdCBzaWduaWZpY2FudCAKCSAgICAgICAgLy8gZGlnaXRzIGlzIG9ubHkgdXNlZCwgd2UgY2FuIHNhZmVseSBkbyBhIGNvbXBhcmUgd2l0aG91dCBtYXNraW5nCgkgICAgICAgIC8vIGlmIHRoZSBjZSBpcyBhIHZhcmlhYmxlLCB3ZSBtYXNrIGFuZCBnZXQgb25seSB0aGUgcHJpbWFyeSB2YWx1ZXMKCSAgICAgICAgLy8gbm8gc2hpZnRpbmcgdG8gcXVhcnRlbmFyeSBpcyByZXF1aXJlZCBzaW5jZSBhbGwgcHJpbWFyeSB2YWx1ZXMKCSAgICAgICAgLy8gbGVzcyB0aGFuIHZhcmlhYmxldG9wIHdpbGwgbmVlZCB0byBiZSBtYXNrZWQgb2ZmIGFueXdheS4KCSAgICAgICAgaWYgKChtX2NvbGxhdG9yXy5tX3ZhcmlhYmxlVG9wVmFsdWVfICA8PCAxNikgPiBjZSkgewoJICAgICAgICAgICAgaWYgKG1fY29sbGF0b3JfLmdldFN0cmVuZ3RoKCkgPT0gQ29sbGF0b3IuUVVBVEVSTkFSWSkgewoJICAgICAgICAgICAgICAgIGNlID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLnByaW1hcnlPcmRlcihjZSk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBlbHNlIHsgCgkgICAgICAgICAgICAgICAgY2UgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgfQoJCgkgICAgcmV0dXJuIGNlOwoJfQoJCgkvKioKCSAqIEFwcGVuZHMgYSBpbnQgdG8gYSBpbnQgYXJyYXksIGluY3JlYXNpbmcgdGhlIHNpemUgb2YgdGhlIGFycmF5IHdoZW4gCgkgKiB3ZSBhcmUgb3V0IG9mIHNwYWNlLgoJICogQHBhcmFtIG9mZnNldCBpbiBhcnJheSB0byBhcHBlbmQgdG8KCSAqIEBwYXJhbSB2YWx1ZSB0byBhcHBlbmQKCSAqIEBwYXJhbSBhcnJheSB0byBhcHBlbmQgdG8KCSAqIEByZXR1cm4gdGhlIGFycmF5IGFwcGVuZGVkIHRvLCB0aGlzIGNvdWxkIGJlIGEgbmV3IGFuZCBiaWdnZXIgYXJyYXkKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50W10gYXBwZW5kKGludCBvZmZzZXQsIGludCB2YWx1ZSwgaW50IGFycmF5W10pCgl7CgkJaWYgKG9mZnNldCA+PSBhcnJheS5sZW5ndGgpIHsKCQkJaW50IHRlbXBbXSA9IG5ldyBpbnRbb2Zmc2V0ICsgSU5JVElBTF9BUlJBWV9TSVpFX107CgkJCVN5c3RlbS5hcnJheWNvcHkoYXJyYXksIDAsIHRlbXAsIDAsIGFycmF5Lmxlbmd0aCk7CgkJCWFycmF5ID0gdGVtcDsKCQl9CgkJYXJyYXlbb2Zmc2V0XSA9IHZhbHVlOwoJCXJldHVybiBhcnJheTsKCX0KCQoJLyoqCgkgKiBJbml0aWFsaXppbmcgdGhlIGNlIHRhYmxlIGZvciBhIHBhdHRlcm4uIFN0b3JlcyBub24taWdub3JhYmxlIGNvbGxhdGlvbiAKCSAqIGtleXMuIFRhYmxlIHNpemUgd2lsbCBiZSBlc3RpbWF0ZWQgYnkgdGhlIHNpemUgb2YgdGhlIHBhdHRlcm4gdGV4dC4gCgkgKiBUYWJsZSBleHBhbnNpb24gd2lsbCBiZSBwZXJmb3JtIGFzIHdlIGdvIGFsb25nLiBBZGRpbmcgMSB0byBlbnN1cmUgdGhhdCAKCSAqIHRoZSB0YWJsZSBzaXplIGRlZmluaXRlbHkgaW5jcmVhc2VzLgoJICogSW50ZXJuYWwgbWV0aG9kLCBzdGF0dXMgYXNzdW1lZCB0byBiZSBhIHN1Y2Nlc3MuCgkgKiBAcmV0dXJuIHRvdGFsIG51bWJlciBvZiBleHBhbnNpb25zIAoJICovCglwcml2YXRlIGZpbmFsIGludCBpbml0aWFsaXplUGF0dGVybkNFVGFibGUoKQoJewoJICAgIG1fdXRpbENvbEVJdGVyXy5zZXRUZXh0KG1fcGF0dGVybl8udGFyZ2V0VGV4dCk7CgkgICAgCgkgICAgaW50IG9mZnNldCA9IDA7CgkgICAgaW50IHJlc3VsdCA9IDA7CgkgICAgaW50IGNlID0gbV91dGlsQ29sRUl0ZXJfLm5leHQoKTsKCQoJICAgIHdoaWxlIChjZSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CgkgICAgICAgIGludCBuZXdjZSA9IGdldENFKGNlKTsKCSAgICAgICAgaWYgKG5ld2NlICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgIG1fcGF0dGVybl8ubV9DRV8gPSBhcHBlbmQob2Zmc2V0LCBuZXdjZSwgbV9wYXR0ZXJuXy5tX0NFXyk7CgkgICAgICAgICAgICBvZmZzZXQgKys7CSAgICAgICAgCgkgICAgICAgIH0KCSAgICAgICAgcmVzdWx0ICs9IG1fdXRpbENvbEVJdGVyXy5nZXRNYXhFeHBhbnNpb24oY2UpIC0gMTsKCSAgICAgICAgY2UgPSBtX3V0aWxDb2xFSXRlcl8ubmV4dCgpOwoJICAgIH0KCQoJICAgIG1fcGF0dGVybl8ubV9DRV8gPSBhcHBlbmQob2Zmc2V0LCAwLCBtX3BhdHRlcm5fLm1fQ0VfKTsKCSAgICBtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfID0gb2Zmc2V0OwoJCgkgICAgcmV0dXJuIHJlc3VsdDsKCX0KCQoJLyoqCgkgKiBJbml0aWFsaXplcyB0aGUgcGF0dGVybiBzdHJ1Y3QuCgkgKiBJbnRlcm5hbCBtZXRob2QsIHN0YXR1cyBhc3N1bWVkIHRvIGJlIHN1Y2Nlc3MuCgkgKiBAcmV0dXJuIGV4cGFuc2lvbnNpemUgdGhlIHRvdGFsIGV4cGFuc2lvbiBzaXplIG9mIHRoZSBwYXR0ZXJuCgkgKi8gCglwcml2YXRlIGZpbmFsIGludCBpbml0aWFsaXplUGF0dGVybigpCgl7CgkgICAgbV9wYXR0ZXJuXy5tX2hhc1ByZWZpeEFjY2VudHNfID0gKGdldEZDRChtX3BhdHRlcm5fLnRhcmdldFRleHQsIDApIAoJICAgIAkJCQkJCQkJCSA+PiBTRUNPTkRfTEFTVF9CWVRFX1NISUZUXykgIT0gMDsKCSAgICBtX3BhdHRlcm5fLm1faGFzU3VmZml4QWNjZW50c18gPSAoZ2V0RkNEKG1fcGF0dGVybl8udGFyZ2V0VGV4dCwgCgkgICAgCQkJCQkJCQkJCSBtX3BhdHRlcm5fLnRhcmdldFRleHQubGVuZ3RoKCkgCgkgICAgCQkJCQkJCQkJCSAtIDEpIAoJICAgIAkJCQkJCQkJCSYgTEFTVF9CWVRFX01BU0tfKSAhPSAwOwoJICAgIC8vIHNpbmNlIGludGlhbGl6ZVBhdHRlcm4gaXMgYW4gaW50ZXJuYWwgbWV0aG9kIHN0YXR1cyBpcyBhIHN1Y2Nlc3MuCgkgICAgcmV0dXJuIGluaXRpYWxpemVQYXR0ZXJuQ0VUYWJsZSgpOyAgIAoJfQoJCgkvKioKCSAqIEluaXRpYWxpemluZyBzaGlmdCB0YWJsZXMsIHdpdGggdGhlIGRlZmF1bHQgdmFsdWVzLgoJICogSWYgYSBjb3JyZXNwb25kaW5nIGRlZmF1bHQgdmFsdWUgaXMgMCwgdGhlIHNoaWZ0IHRhYmxlIGlzIG5vdCBzZXQuCgkgKiBAcGFyYW0gc2hpZnQgdGFibGUgZm9yIGZvcndhcmRzIHNoaWZ0IAoJICogQHBhcmFtIGJhY2tzaGlmdCB0YWJsZSBmb3IgYmFja3dhcmRzIHNoaWZ0CgkgKiBAcGFyYW0gY2V0YWJsZSB0YWJsZSBjb250YWluaW5nIHBhdHRlcm4gY2UKCSAqIEBwYXJhbSBjZXNpemUgc2l6ZSBvZiB0aGUgcGF0dGVybiBjZXMKCSAqIEBwYXJhbSBleHBhbnNpb25zaXplIHRvdGFsIHNpemUgb2YgdGhlIGV4cGFuc2lvbnMKCSAqIEBwYXJhbSBkZWZhdWx0Zm9yd2FyZCB0aGUgZGVmYXVsdCBmb3J3YXJkIHZhbHVlCgkgKiBAcGFyYW0gZGVmYXVsdGJhY2t3YXJkIHRoZSBkZWZhdWx0IGJhY2t3YXJkIHZhbHVlCgkgKi8KCSBwcml2YXRlIGZpbmFsIHZvaWQgc2V0U2hpZnRUYWJsZShjaGFyIHNoaWZ0W10sIAoJIAkJCQkJCQkJCQkJICAgY2hhciBiYWNrc2hpZnRbXSwgCgkJCQkJICAgICAgICAgICAgICAgICAgICAgICAgIAkgICBpbnQgY2V0YWJsZVtdLCBpbnQgY2VzaXplLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAJCQkJCSAJICAgaW50IGV4cGFuc2lvbnNpemUsCgkJCQkJICAgICAgICAgICAgICAgICAgICAgICAgIAkgICBjaGFyIGRlZmF1bHRmb3J3YXJkLAogICAgICAgICAgICAgICAgICAgICAgICAgIAkJCQkJIAkgICBjaGFyIGRlZmF1bHRiYWNrd2FyZCkKCXsKCSAgICAvLyBlc3RpbWF0ZSB0aGUgdmFsdWUgdG8gc2hpZnQuIHRvIGRvIHRoYXQgd2UgZXN0aW1hdGUgdGhlIHNtYWxsZXN0IAoJICAgIC8vIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIGdpdmUgdGhlIHJlbGV2YW50IGNlcywgaWUgYXBwcm94aW1hdGVseQoJICAgIC8vIHRoZSBudW1iZXIgb2YgY2VzIG1pbnVzIHRoZWlyIGV4cGFuc2lvbiwgc2luY2UgZXhwYW5zaW9ucyBjYW4gY29tZSAKCSAgICAvLyBmcm9tIGEgY2hhcmFjdGVyLgoJICAgIGZvciAoaW50IGNvdW50ID0gMDsgY291bnQgPCBNQVhfVEFCTEVfU0laRV87IGNvdW50ICsrKSB7CgkgICAgICAgIHNoaWZ0W2NvdW50XSA9IGRlZmF1bHRmb3J3YXJkOwoJICAgIH0KCSAgICBjZXNpemUgLS07IC8vIGRvd24gdG8gdGhlIGxhc3QgaW5kZXgKCSAgICBmb3IgKGludCBjb3VudCA9IDA7IGNvdW50IDwgY2VzaXplOyBjb3VudCArKykgewoJICAgICAgICAvLyBudW1iZXIgb2YgY2VzIGZyb20gcmlnaHQgb2YgYXJyYXkgdG8gdGhlIGNvdW50CgkgICAgICAgIGludCB0ZW1wID0gZGVmYXVsdGZvcndhcmQgLSBjb3VudCAtIDE7CgkgICAgICAgIHNoaWZ0W2hhc2goY2V0YWJsZVtjb3VudF0pXSA9IHRlbXAgPiAxID8gKChjaGFyKXRlbXApIDogMTsKCSAgICB9CgkgICAgc2hpZnRbaGFzaChjZXRhYmxlW2Nlc2l6ZV0pXSA9IDE7CgkgICAgLy8gZm9yIGlnbm9yYWJsZXMgd2UganVzdCBzaGlmdCBieSBvbmUuIHNlZSB0ZXN0IGV4YW1wbGVzLgoJICAgIHNoaWZ0W2hhc2goMCldID0gMTsKCSAgICAKCSAgICBmb3IgKGludCBjb3VudCA9IDA7IGNvdW50IDwgTUFYX1RBQkxFX1NJWkVfOyBjb3VudCArKykgewoJICAgICAgICBiYWNrc2hpZnRbY291bnRdID0gZGVmYXVsdGJhY2t3YXJkOwoJICAgIH0KCSAgICBmb3IgKGludCBjb3VudCA9IGNlc2l6ZTsgY291bnQgPiAwOyBjb3VudCAtLSkgewoJICAgICAgICAvLyB0aGUgb3JpZ2luYWwgdmFsdWUgY291bnQgZG9lcyBub3Qgc2VlbSB0byB3b3JrCgkgICAgICAgIGJhY2tzaGlmdFtoYXNoKGNldGFibGVbY291bnRdKV0gPSAoY2hhcikoY291bnQgPiBleHBhbnNpb25zaXplID8gCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAJCWNvdW50IC0gZXhwYW5zaW9uc2l6ZSA6IDEpOwoJICAgIH0KCSAgICBiYWNrc2hpZnRbaGFzaChjZXRhYmxlWzBdKV0gPSAxOwoJICAgIGJhY2tzaGlmdFtoYXNoKDApXSA9IDE7Cgl9CgkKCS8qKgoJICogPHA+QnVpbGRpbmcgb2YgdGhlIHBhdHRlcm4gY29sbGF0aW9uIGVsZW1lbnQgbGlzdCBhbmQgdGhlIEJveWVyIE1vb3JlIAoJICogU3RyaW5nU2VhcmNoIHRhYmxlLjwvcD4KCSAqIDxwPlRoZSBjYW5vbmljYWwgbWF0Y2ggd2lsbCBvbmx5IGJlIHBlcmZvcm1lZCBhZnRlciB0aGUgZGVmYXVsdCBtYXRjaCAKCSAqIGZhaWxzLjwvcD4KCSAqIDxwPkZvciBib3RoIGNhc2VzIHdlIG5lZWQgdG8gcmVtZW1iZXIgdGhlIHNpemUgb2YgdGhlIGNvbXBvc2VkIGFuZCAKCSAqIGRlY29tcG9zZWQgdmVyc2lvbnMgb2YgdGhlIHN0cmluZy4gU2luY2UgdGhlIEJveWVyLU1vb3JlIHNoaWZ0IAoJICogY2FsY3VsYXRpb25zIHNoaWZ0cyBieSBhIG51bWJlciBvZiBjaGFyYWN0ZXJzIGluIHRoZSB0ZXh0IGFuZCB0cmllcyB0byAKCSAqIG1hdGNoIHRoZSBwYXR0ZXJuIGZyb20gdGhhdCBvZmZzZXQsIHRoZSBzaGlmdCB2YWx1ZSBjYW4gbm90IGJlIHRvbyBsYXJnZSAKCSAqIGluIGNhc2Ugd2UgbWlzcyBzb21lIGNoYXJhY3RlcnMuIFRvIGNob29zZSBhIHJpZ2h0IHNoaWZ0IHNpemUsIHdlIAoJICogZXN0aW1hdGUgdGhlIE5GQyBmb3JtIG9mIHRoZSBhbmQgdXNlIGl0cyBzaXplIGFzIGEgc2hpZnQgZ3VpZGUuIFRoZSBORkMgCgkgKiBmb3JtIHNob3VsZCBiZSB0aGUgc21hbGwgcG9zc2libGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhdHRlcm4uIEFueXdheXMsIAoJICogd2UnbGwgZXJyIG9uIHRoZSBzbWFsbGVyIHNoaWZ0IHNpemUuIEhlbmNlIHRoZSBjYWxjdWxhdGlvbiBmb3IgCgkgKiBtaW5sZW5ndGguIENhbm9uaWNhbCBtYXRjaCB3aWxsIGJlIHBlcmZvcm1lZCBzbGlnaHRseSBkaWZmZXJlbnRseS4gV2UnbGwgCgkgKiBzcGxpdCB0aGUgcGF0dGVybiBpbnRvIDMgcGFydHMsIHRoZSBwcmVmaXggYWNjZW50cyAoUEEpLCB0aGUgbWlkZGxlIAoJICogc3RyaW5nIGJvdW5kZWQgYnkgdGhlIGZpcnN0IGFuZCBsYXN0IGJhc2UgY2hhcmFjdGVyIChNUyksIHRoZSBlbmRpbmcgCgkgKiBhY2NlbnRzIChFQSkuIE1hdGNoZXMgd2lsbCBiZSBkb25lIG9uIE1TIGZpcnN0LCBhbmQgb25seSB3aGVuIHdlIG1hdGNoIAoJICogTVMgdGhlbiBzb21lIHByb2Nlc3Npbmcgd2lsbCBiZSByZXF1aXJlZCBmb3IgdGhlIHByZWZpeCBhbmQgZW5kIGFjY2VudHMgCgkgKiBpbiBvcmRlciB0byBkZXRlcm1pbmUgaWYgdGhleSBtYXRjaCBQQSBhbmQgRUEuIEhlbmNlIHRoZSBkZWZhdWx0IHNoaWZ0IAoJICogdmFsdWVzIGZvciB0aGUgY2Fub25pY2FsIG1hdGNoIHdpbGwgdGFrZSB0aGUgc2l6ZSBvZiBlaXRoZXIgZW5kJ3MgYWNjZW50IAoJICogaW50byBjb25zaWRlcmF0aW9uLiBGb3J3YXJkcyBzZWFyY2ggd2lsbCB0YWtlIHRoZSBlbmQgYWNjZW50cyBpbnRvIAoJICogY29uc2lkZXJhdGlvbiBmb3IgdGhlIGRlZmF1bHQgc2hpZnQgdmFsdWVzIGFuZCB0aGUgYmFja3dhcmRzIHNlYXJjaCB3aWxsIAoJICogdGFrZSB0aGUgcHJlZml4IGFjY2VudHMgaW50byBjb25zaWRlcmF0aW9uLjwvcD4KCSAqIDxwPklmIHBhdHRlcm4gaGFzIG5vIG5vbi1pZ25vcmFibGUgY2UsIHdlIHJldHVybiBhIGlsbGVnYWwgYXJndW1lbnQgCgkgKiBlcnJvci48L3A+CgkgKi8gCglwcml2YXRlIGZpbmFsIHZvaWQgaW5pdGlhbGl6ZSgpCgl7CgkgICAgaW50IGV4cGFuZGxlbmd0aCAgPSBpbml0aWFsaXplUGF0dGVybigpOyAgIAoJICAgIGlmIChtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfID4gMCkgewoJICAgICAgICBjaGFyIG1pbmxlbmd0aCA9IChjaGFyKShtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfID4gZXhwYW5kbGVuZ3RoIAoJICAgICAgICAJCQkJCT8gbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyAtIGV4cGFuZGxlbmd0aCA6IDEpOwoJICAgICAgICBtX3BhdHRlcm5fLm1fZGVmYXVsdFNoaWZ0U2l6ZV8gPSBtaW5sZW5ndGg7CiAgICAgICAgICAgIHNldFNoaWZ0VGFibGUobV9wYXR0ZXJuXy5tX3NoaWZ0XywgbV9wYXR0ZXJuXy5tX2JhY2tTaGlmdF8sIAoJICAgICAgICAJCQkgIG1fcGF0dGVybl8ubV9DRV8sIG1fcGF0dGVybl8ubV9DRUxlbmd0aF8sIAoJICAgICAgICAJCQkgIGV4cGFuZGxlbmd0aCwgbWlubGVuZ3RoLCBtaW5sZW5ndGgpOwoJICAgIH0KCSAgICBlbHNlIHsKCSAgICAJbV9wYXR0ZXJuXy5tX2RlZmF1bHRTaGlmdFNpemVfID0gMDsKCSAgICB9Cgl9CgkKCS8qKgoJICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIHNlYXJjaCB0ZXh0IGJvdW5kZWQgYnkgdGhlIG9mZnNldCBzdGFydCBhbmQgZW5kIGlzIAoJICogb25lIG9yIG1vcmUgd2hvbGUgdW5pdHMgb2YgdGV4dCBhcyBkZXRlcm1pbmVkIGJ5IHRoZSBicmVha2l0ZXJhdG9yIGluIAoJICogU3RyaW5nU2VhcmNoLgoJICogQHBhcmFtIHN0YXJ0IHRhcmdldCB0ZXh0IHN0YXJ0IG9mZnNldAoJICogQHBhcmFtIGVuZCB0YXJnZXQgdGV4dCBlbmQgb2Zmc2V0CgkgKi8KCXByaXZhdGUgZmluYWwgYm9vbGVhbiBpc0JyZWFrVW5pdChpbnQgc3RhcnQsIGludCBlbmQpIAoJewoJICAgIGlmIChicmVha0l0ZXJhdG9yICE9IG51bGwpIHsKCSAgICAgICAgaW50IHN0YXJ0aW5kZXggPSBicmVha0l0ZXJhdG9yLmZpcnN0KCk7CgkgICAgICAgIGludCBlbmRpbmRleCAgID0gYnJlYWtJdGVyYXRvci5sYXN0KCk7CgkgICAgICAgIAoJICAgICAgICAvLyBvdXQtb2YtcmFuZ2UgaW5kZXhlcyBhcmUgbmV2ZXIgYm91bmRhcnkgcG9zaXRpb25zCgkgICAgICAgIGlmIChzdGFydCA8IHN0YXJ0aW5kZXggfHwgc3RhcnQgPiBlbmRpbmRleCB8fCBlbmQgPCBzdGFydGluZGV4IAoJICAgICAgICAJfHwgZW5kID4gZW5kaW5kZXgpIHsKCSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICAgICAgfQoJICAgICAgICAvLyBvdGhlcndpc2UsIHdlIGNhbiB1c2UgZm9sbG93aW5nKCkgb24gdGhlIHBvc2l0aW9uIGJlZm9yZSB0aGUgCgkgICAgICAgIC8vIHNwZWNpZmllZCBvbmUgYW5kIHJldHVybiB0cnVlIG9mIHRoZSBwb3NpdGlvbiB3ZSBnZXQgYmFjayBpcyB0aGUgCgkgICAgICAgIC8vIG9uZSB0aGUgdXNlciBzcGVjaWZpZWQKCSAgICAgICAgYm9vbGVhbiByZXN1bHQgPSAoc3RhcnQgPT0gc3RhcnRpbmRleCAKCSAgICAgICAgCQkJCSAgfHwgYnJlYWtJdGVyYXRvci5mb2xsb3dpbmcoc3RhcnQgLSAxKSA9PSBzdGFydCkgCgkgICAgICAgIAkJCQkgJiYgKGVuZCA9PSBlbmRpbmRleCAKCSAgICAgICAgCQkJCSAJIHx8IGJyZWFrSXRlcmF0b3IuZm9sbG93aW5nKGVuZCAtIDEpID09IGVuZCk7CgkgICAgICAgIGlmIChyZXN1bHQpIHsKCSAgICAgICAgICAgIC8vIGl0ZXJhdGVzIHRoZSBpbmRpdmlkdWFsIGNlcwoJICAgICAgICAgICAgbV91dGlsQ29sRUl0ZXJfLnNldFRleHQodGFyZ2V0VGV4dCk7CgkgICAgICAgICAgICBtX3V0aWxDb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQoc3RhcnQpOwoJICAgICAgICAgICAgZm9yIChpbnQgY291bnQgPSAwOyBjb3VudCA8IG1fcGF0dGVybl8ubV9DRUxlbmd0aF87CgkgICAgICAgICAgICAgICAgIGNvdW50ICsrKSB7CgkgICAgICAgICAgICAgICAgaWYgKGdldENFKG1fdXRpbENvbEVJdGVyXy5uZXh0KCkpIAoJICAgICAgICAgICAgICAgIAkhPSBtX3BhdHRlcm5fLm1fQ0VfW2NvdW50XSkgewoJICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKG1fdXRpbENvbEVJdGVyXy5uZXh0KCkgCgkgICAgICAgICAgICAJCSE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIgCgkgICAgICAgICAgICAJJiYgbV91dGlsQ29sRUl0ZXJfLmdldE9mZnNldCgpID09IGVuZCkgewoJICAgICAgICAgICAgICAgIC8vIGV4dHJhIGNvbGxhdGlvbiBlbGVtZW50cyBhdCB0aGUgZW5kIG9mIHRoZSBtYXRjaAoJICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgICAgICByZXR1cm4gcmVzdWx0OwoJICAgIH0KCSAgICByZXR1cm4gdHJ1ZTsKCX0KCQoJLyoqCgkgKiBHZXR0aW5nIHRoZSBuZXh0IGJhc2UgY2hhcmFjdGVyIG9mZnNldCBpZiBjdXJyZW50IG9mZnNldCBpcyBhbiBhY2NlbnQsIAoJICogb3IgdGhlIGN1cnJlbnQgb2Zmc2V0IGlmIHRoZSBjdXJyZW50IGNoYXJhY3RlciBjb250YWlucyBhIGJhc2UgY2hhcmFjdGVyLiAKCSAqIGFjY2VudHMgdGhlIGZvbGxvd2luZyBiYXNlIGNoYXJhY3RlciB3aWxsIGJlIHJldHVybmVkCgkgKiBAcGFyYW0gdGV4dCBzdHJpbmcKCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IGN1cnJlbnQgb2Zmc2V0CgkgKiBAcGFyYW0gdGV4dGxlbmd0aCBsZW5ndGggb2YgdGV4dCBzdHJpbmcKCSAqIEByZXR1cm4gdGhlIG5leHQgYmFzZSBjaGFyYWN0ZXIgb3IgdGhlIGN1cnJlbnQgb2Zmc2V0CgkgKiAgICAgICAgIGlmIHRoZSBjdXJyZW50IGNoYXJhY3RlciBpcyBjb250YWlucyBhIGJhc2UgY2hhcmFjdGVyLgoJICovCglwcml2YXRlIGZpbmFsIGludCBnZXROZXh0QmFzZU9mZnNldChDaGFyYWN0ZXJJdGVyYXRvciB0ZXh0LCAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAJCSBpbnQgdGV4dG9mZnNldCkKCXsKCSAgICBpZiAodGV4dG9mZnNldCA8IHRleHQuZ2V0RW5kSW5kZXgoKSkgewoJICAgICAgICB3aGlsZSAodGV4dC5nZXRJbmRleCgpIDwgdGV4dC5nZXRFbmRJbmRleCgpKSB7IAoJICAgICAgICAgICAgaW50IHJlc3VsdCA9IHRleHRvZmZzZXQ7CgkgICAgICAgICAgICBpZiAoKGdldEZDRCh0ZXh0LCB0ZXh0b2Zmc2V0ICsrKSAKCSAgICAgICAgICAgICAgICAJCT4+IFNFQ09ORF9MQVNUX0JZVEVfU0hJRlRfKSA9PSAwKSB7CgkgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICAgICAgcmV0dXJuIHRleHQuZ2V0RW5kSW5kZXgoKTsKCSAgICB9CgkgICAgcmV0dXJuIHRleHRvZmZzZXQ7Cgl9CgkKCS8qKgoJICogR2V0cyB0aGUgbmV4dCBiYXNlIGNoYXJhY3RlciBvZmZzZXQgZGVwZW5kaW5nIG9uIHRoZSBzdHJpbmcgc2VhcmNoIAoJICogcGF0dGVybiBkYXRhCgkgKiBAcGFyYW0gdGV4dG9mZnNldCBvbmUgb2Zmc2V0IGF3YXkgZnJvbSB0aGUgbGFzdCBjaGFyYWN0ZXIKCSAqICAgICAgICAgICAgICAgICAgIHRvIHNlYXJjaCBmb3IuCgkgKiBAcmV0dXJuIHN0YXJ0IGluZGV4IG9mIHRoZSBuZXh0IGJhc2UgY2hhcmFjdGVyIG9yIHRoZSBjdXJyZW50IG9mZnNldAoJICogICAgICAgICBpZiB0aGUgY3VycmVudCBjaGFyYWN0ZXIgaXMgY29udGFpbnMgYSBiYXNlIGNoYXJhY3Rlci4KCSAqLwoJcHJpdmF0ZSBmaW5hbCBpbnQgZ2V0TmV4dEJhc2VPZmZzZXQoaW50IHRleHRvZmZzZXQpCgl7CgkgICAgaWYgKG1fcGF0dGVybl8ubV9oYXNTdWZmaXhBY2NlbnRzXyAKCSAgICAJJiYgdGV4dG9mZnNldCA8IG1fdGV4dExpbWl0T2Zmc2V0XykgewogICAgICAgICAgICB0YXJnZXRUZXh0LnNldEluZGV4KHRleHRvZmZzZXQpOwogICAgICAgICAgICB0YXJnZXRUZXh0LnByZXZpb3VzKCk7CiAgICAgICAgICAgIGlmICgoZ2V0RkNEKHRhcmdldFRleHQsIHRhcmdldFRleHQuZ2V0SW5kZXgoKSkgJiBMQVNUX0JZVEVfTUFTS18pICE9IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiBnZXROZXh0QmFzZU9mZnNldCh0YXJnZXRUZXh0LCB0ZXh0b2Zmc2V0KTsKICAgICAgICAgICAgfQoJICAgIH0KCSAgICByZXR1cm4gdGV4dG9mZnNldDsKCX0KCQoJLyoqCgkgKiBTaGlmdGluZyB0aGUgY29sbGF0aW9uIGVsZW1lbnQgaXRlcmF0b3IgcG9zaXRpb24gZm9yd2FyZCB0byBwcmVwYXJlIGZvcgoJICogYSBmb2xsb3dpbmcgbWF0Y2guIElmIHRoZSBsYXN0IGNoYXJhY3RlciBpcyBhIHVuc2FmZSBjaGFyYWN0ZXIsIHdlJ2xsIAoJICogb25seSBzaGlmdCBieSAxIHRvIGNhcHR1cmUgY29udHJhY3Rpb25zLCBub3JtYWxpemF0aW9uIGV0Yy4KCSAqIEludGVybmFsIG1ldGhvZCwgc3RhdHVzIGFzc3VtZWQgdG8gYmUgc3VjY2Vzcy4KCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IHN0YXJ0IHRleHQgcG9zaXRpb24gdG8gZG8gc2VhcmNoCgkgKiBAcGFyYW0gY2UgdGhlIHRleHQgY2Ugd2hpY2ggZmFpbGVkIHRoZSBtYXRjaC4KCSAqIEBwYXJhbSBwYXR0ZXJuY2VpbmRleCBpbmRleCBvZiB0aGUgY2Ugd2l0aGluIHRoZSBwYXR0ZXJuIGNlIGJ1ZmZlciB3aGljaAoJICogICAgICAgIGZhaWxlZCB0aGUgbWF0Y2gKCSAqIEByZXR1cm4gZmluYWwgb2Zmc2V0CgkgKi8KCXByaXZhdGUgaW50IHNoaWZ0Rm9yd2FyZChpbnQgdGV4dG9mZnNldCwgaW50IGNlLCBpbnQgcGF0dGVybmNlaW5kZXgpCgkJCQkJCQkJCQoJewoJICAgIGlmIChpc092ZXJsYXBwaW5nKCkpIHsKCSAgICAgICAgaWYgKHRleHRvZmZzZXQgPiBtX3RleHRCZWdpbk9mZnNldF8pIHsKCSAgICAgICAgICAgIHRleHRvZmZzZXQgKys7CgkgICAgICAgIH0KCSAgICAgICAgZWxzZSB7CgkgICAgICAgICAgICB0ZXh0b2Zmc2V0ID0gbV9wYXR0ZXJuXy5tX2RlZmF1bHRTaGlmdFNpemVfOwoJICAgICAgICB9CgkgICAgfQoJICAgIGVsc2UgewoJICAgICAgICBpZiAoY2UgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewoJICAgICAgICAgICAgaW50IHNoaWZ0ID0gbV9wYXR0ZXJuXy5tX3NoaWZ0X1toYXNoKGNlKV07CgkgICAgICAgICAgICAvLyB0aGlzIGlzIHRvIGFkanVzdCBmb3IgY2hhcmFjdGVycyBpbiB0aGUgbWlkZGxlIG9mIHRoZSAKCSAgICAgICAgICAgIC8vIHN1YnN0cmluZyBmb3IgbWF0Y2hpbmcgdGhhdCBmYWlsZWQuCgkgICAgICAgICAgICBpbnQgYWRqdXN0ID0gbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyAtIHBhdHRlcm5jZWluZGV4OwoJICAgICAgICAgICAgaWYgKGFkanVzdCA+IDEgJiYgc2hpZnQgPj0gYWRqdXN0KSB7CgkgICAgICAgICAgICAgICAgc2hpZnQgLT0gYWRqdXN0IC0gMTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHRleHRvZmZzZXQgKz0gc2hpZnQ7CgkgICAgICAgIH0KCSAgICAgICAgZWxzZSB7CgkgICAgICAgICAgICB0ZXh0b2Zmc2V0ICs9IG1fcGF0dGVybl8ubV9kZWZhdWx0U2hpZnRTaXplXzsKCSAgICAgICAgfQoJICAgIH0KCSAgICAgCiAgICAgICAgdGV4dG9mZnNldCA9IGdldE5leHRCYXNlT2Zmc2V0KHRleHRvZmZzZXQpOwoJICAgIC8vIGNoZWNrIGZvciB1bnNhZmUgY2hhcmFjdGVycwoJICAgIC8vICogaWYgaXQgaXMgdGhlIHN0YXJ0IG9yIG1pZGRsZSBvZiBhIGNvbnRyYWN0aW9uOiB0byBiZSBkb25lIGFmdGVyIAoJICAgIC8vICAgYSBpbml0aWFsIG1hdGNoIGlzIGZvdW5kCgkgICAgLy8gKiB0aGFpIG9yIGxhbyBiYXNlIGNvbnNvbmFudCBjaGFyYWN0ZXI6IHNpbWlsYXIgdG8gY29udHJhY3Rpb24KCSAgICAvLyAqIGhpZ2ggc3Vycm9nYXRlIGNoYXJhY3Rlcjogc2ltaWxhciB0byBjb250cmFjdGlvbgoJICAgIC8vICogbmV4dCBjaGFyYWN0ZXIgaXMgYSBhY2NlbnQ6IHNoaWZ0IHRvIHRoZSBuZXh0IGJhc2UgY2hhcmFjdGVyCgkgICAgcmV0dXJuIHRleHRvZmZzZXQ7Cgl9CgkKCS8qKgoJICogR2V0cyB0aGUgb2Zmc2V0IHRvIHRoZSBuZXh0IHNhZmUgcG9pbnQgaW4gdGV4dC4KCSAqIGllLiBub3QgdGhlIG1pZGRsZSBvZiBhIGNvbnRyYWN0aW9uLCBzd2FwcGFibGUgY2hhcmFjdGVycyBvciAKCSAqIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVycy4KCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IG9mZnNldCBpbiBzdHJpbmcKCSAqIEBwYXJhbSBlbmQgb2Zmc2V0IGluIHN0cmluZwoJICogQHJldHVybiBvZmZzZXQgdG8gdGhlIG5leHQgc2FmZSBjaGFyYWN0ZXIKCSAqLwoJcHJpdmF0ZSBmaW5hbCBpbnQgZ2V0TmV4dFNhZmVPZmZzZXQoaW50IHRleHRvZmZzZXQsIGludCBlbmQpCgl7CgkgICAgaW50IHJlc3VsdCA9IHRleHRvZmZzZXQ7IC8vIGZpcnN0IGNvbnRyYWN0aW9uIGNoYXJhY3RlcgoJICAgIHRhcmdldFRleHQuc2V0SW5kZXgocmVzdWx0KTsKCSAgICB3aGlsZSAocmVzdWx0ICE9IGVuZCAmJiAKCSAgICAJbV9jb2xsYXRvcl8uaXNVbnNhZmUodGFyZ2V0VGV4dC5jdXJyZW50KCkpKSB7CgkgICAgICAgCXJlc3VsdCArKzsKCSAgICAgICAJdGFyZ2V0VGV4dC5zZXRJbmRleChyZXN1bHQpOwoJICAgIH0KCSAgICByZXR1cm4gcmVzdWx0OyAKCX0KCQoJLyoqIAoJICogVGhpcyBjaGVja3MgZm9yIGFjY2VudHMgaW4gdGhlIHBvdGVudGlhbCBtYXRjaCBzdGFydGVkIHdpdGggYSBjb21wb3NpdGUgCgkgKiBjaGFyYWN0ZXIuCgkgKiBUaGlzIGlzIHJlYWxseSBwYWluZnVsLi4uIHdlIGhhdmUgdG8gY2hlY2sgdGhhdCBjb21wb3NpdGUgY2hhcmFjdGVyIGRvIAoJICogbm90IGhhdmUgYW55IGV4dHJhIGFjY2VudHMuIFdlIGhhdmUgdG8gbm9ybWFsaXplIHRoZSBwb3RlbnRpYWwgbWF0Y2ggYW5kIAoJICogZmluZCB0aGUgaW1tZWRpYXRlIGRlY29tcG9zZWQgY2hhcmFjdGVyIGJlZm9yZSB0aGUgbWF0Y2guCgkgKiBUaGUgZmlyc3QgY29tcG9zaXRlIGNoYXJhY3RlciB3b3VsZCBoYXZlIGJlZW4gdGFrZW4gY2FyZSBvZiBieSB0aGUgZmNkIAoJICogY2hlY2tzIGluIGNoZWNrRm9yd2FyZEV4YWN0TWF0Y2guCgkgKiBUaGlzIGlzIHRoZSBzbG93IHBhdGggYWZ0ZXIgdGhlIGZjZCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGFuZCAKCSAqIHRoZSBsYXN0IGNoYXJhY3RlciBoYXMgYmVlbiBjaGVja2VkIGJ5IGNoZWNrRm9yd2FyZEV4YWN0TWF0Y2ggYW5kIHdlIAoJICogZGV0ZXJtaW5lIHRoYXQgdGhlIHBvdGVudGlhbCBtYXRjaCBoYXMgZXh0cmEgbm9uLWlnbm9yYWJsZSBwcmVjZWRpbmcKCSAqIGNlcy4KCSAqIEUuZy4gbG9va2luZyBmb3IgXHUwMzAxIGFjdXRlIGluIFx1MDFGQSBBIHJpbmcgYWJvdmUgYW5kIGFjdXRlLCAKCSAqIGNoZWNrRXh0cmFNYXRjaEFjY2VudCBzaG91bGQgZmFpbCBzaW5jZSB0aGVyZSBpcyBhIG1pZGRsZSByaW5nIGluIAoJICogXHUwMUZBIE5vdGUgaGVyZSB0aGF0IGFjY2VudHMgY2hlY2tpbmcgYXJlIHNsb3cgYW5kIGNhdXRpb25lZCBpbiB0aGUgQVBJIAoJICogZG9jcy4KCSAqIEludGVybmFsIG1ldGhvZCwgc3RhdHVzIGFzc3VtZWQgdG8gYmUgYSBzdWNjZXNzLCBjYWxsZXIgc2hvdWxkIGNoZWNrIAoJICogc3RhdHVzIGJlZm9yZSBjYWxsaW5nIHRoaXMgbWV0aG9kCgkgKiBAcGFyYW0gc3RhcnQgaW5kZXggb2YgdGhlIHBvdGVudGlhbCB1bmZyaWVuZGx5IGNvbXBvc2l0ZSBjaGFyYWN0ZXIKCSAqIEBwYXJhbSBlbmQgaW5kZXggb2YgdGhlIHBvdGVudGlhbCB1bmZyaWVuZGx5IGNvbXBvc2l0ZSBjaGFyYWN0ZXIKCSAqIEByZXR1cm4gdHJ1ZSBpZiB0aGVyZSBpcyBub24taWdub3JhYmxlIGFjY2VudHMgYmVmb3JlIGF0IHRoZSBiZWdpbm5pbmcKCSAqICAgICAgICAgICAgICBvZiB0aGUgbWF0Y2gsIGZhbHNlIG90aGVyd2lzZS4KCSAqLwoJcHJpdmF0ZSBmaW5hbCBib29sZWFuIGNoZWNrRXh0cmFNYXRjaEFjY2VudHMoaW50IHN0YXJ0LCBpbnQgZW5kKQoJewoJICAgIGJvb2xlYW4gcmVzdWx0ID0gZmFsc2U7CgkgICAgaWYgKG1fcGF0dGVybl8ubV9oYXNQcmVmaXhBY2NlbnRzXykgewoJICAgICAgICB0YXJnZXRUZXh0LnNldEluZGV4KHN0YXJ0KTsKCSAgICAgICAgCgkgICAgICAgIGlmIChVVEYxNi5pc0xlYWRTdXJyb2dhdGUodGFyZ2V0VGV4dC5uZXh0KCkpKSB7CgkgICAgICAgIAlpZiAoIVVURjE2LmlzVHJhaWxTdXJyb2dhdGUodGFyZ2V0VGV4dC5uZXh0KCkpKSB7CgkgICAgICAgIAkJdGFyZ2V0VGV4dC5wcmV2aW91cygpOwoJICAgICAgICAJfQoJICAgICAgICB9CgkgICAgICAgIC8vIHdlIGFyZSBvbmx5IGNvbmNlcm5lZCB3aXRoIHRoZSBmaXJzdCBjb21wb3NpdGUgY2hhcmFjdGVyCgkgICAgICAgIFN0cmluZyBzdHIgPSBnZXRTdHJpbmcodGFyZ2V0VGV4dCwgc3RhcnQsIGVuZCk7CgkgICAgICAgIGlmIChOb3JtYWxpemVyLnF1aWNrQ2hlY2soc3RyLCBOb3JtYWxpemVyLk5GRCkgCgkgICAgICAgIAkJCQkJCQkJCQk9PSBOb3JtYWxpemVyLk5PKSB7CgkgICAgICAgICAgICBpbnQgc2FmZW9mZnNldCA9IGdldE5leHRTYWZlT2Zmc2V0KHN0YXJ0LCBlbmQpOwoJICAgICAgICAgICAgaWYgKHNhZmVvZmZzZXQgIT0gZW5kKSB7CgkgICAgICAgICAgICAgICAgc2FmZW9mZnNldCArKzsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIFN0cmluZyBkZWNvbXAgPSBOb3JtYWxpemVyLmRlY29tcG9zZSgKCSAgICAgICAgICAgIAkJCQlzdHIuc3Vic3RyaW5nKDAsIHNhZmVvZmZzZXQgLSBzdGFydCksIGZhbHNlKTsKCSAgICAgICAgICAgIG1fdXRpbENvbEVJdGVyXy5zZXRUZXh0KGRlY29tcCk7CgkgICAgICAgICAgICBpbnQgZmlyc3RjZSA9IG1fcGF0dGVybl8ubV9DRV9bMF07CgkgICAgICAgICAgICBib29sZWFuIGlnbm9yYWJsZSA9IHRydWU7CgkgICAgICAgICAgICBpbnQgY2UgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFOwoJICAgICAgICAgICAgaW50IG9mZnNldCA9IDA7CgkgICAgICAgICAgICB3aGlsZSAoY2UgIT0gZmlyc3RjZSkgewoJICAgICAgICAgICAgCW9mZnNldCA9IG1fdXRpbENvbEVJdGVyXy5nZXRPZmZzZXQoKTsKCSAgICAgICAgICAgICAgICBpZiAoY2UgIT0gZmlyc3RjZSAKCSAgICAgICAgICAgICAgICAJJiYgY2UgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgICAgICAgICBpZ25vcmFibGUgPSBmYWxzZTsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgY2UgPSBtX3V0aWxDb2xFSXRlcl8ubmV4dCgpOwoJICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbV91dGlsQ29sRUl0ZXJfLnNldEV4YWN0T2Zmc2V0KG9mZnNldCk7IC8vIGJhY2sgdXAgMSB0byB0aGUgCiAgICAgICAgICAgICAgICBtX3V0aWxDb2xFSXRlcl8ucHJldmlvdXMoKTsgICAgICAgICAgICAgLy8gcmlnaHQgb2Zmc2V0CiAgICAgICAgICAgICAgICBvZmZzZXQgPSBtX3V0aWxDb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CiAgICAgICAgICAgICAgICByZXN1bHQgPSAhaWdub3JhYmxlICYmIChVQ2hhcmFjdGVyLmdldENvbWJpbmluZ0NsYXNzKAoJICAgICAgICAgICAgCQkJCQkJCVVURjE2LmNoYXJBdChkZWNvbXAsIG9mZnNldCkpICE9IDApOwoJICAgICAgICB9CgkgICAgfQoJCgkgICAgcmV0dXJuIHJlc3VsdDsKCX0KCQoJLyoqCgkqIFVzZWQgYnkgZXhhY3QgbWF0Y2hlcywgY2hlY2tzIGlmIHRoZXJlIGFyZSBhY2NlbnRzIGJlZm9yZSB0aGUgbWF0Y2guIAoJKiBUaGlzIGlzIHJlYWxseSBwYWluZnVsLi4uIHdlIGhhdmUgdG8gY2hlY2sgdGhhdCBjb21wb3NpdGUgY2hhcmFjdGVycyBhdAoJKiB0aGUgc3RhcnQgb2YgdGhlIG1hdGNoZXMgaGF2ZSB0byBub3QgaGF2ZSBhbnkgZXh0cmEgYWNjZW50cy4gCgkqIFdlIGNoZWNrIHRoZSBGQ0Qgb2YgdGhlIGNoYXJhY3RlciBmaXJzdCwgaWYgaXQgc3RhcnRzIHdpdGggYW4gYWNjZW50IGFuZCAKCSogdGhlIGZpcnN0IHBhdHRlcm4gY2UgZG9lcyBub3QgbWF0Y2ggdGhlIGZpcnN0IGNlIG9mIHRoZSBjaGFyYWN0ZXIsIHdlIAoJKiBiYWlsLgoJKiBPdGhlcndpc2Ugd2UgdHJ5IG5vcm1hbGl6aW5nIHRoZSBmaXJzdCBjb21wb3NpdGUgCgkqIGNoYXJhY3RlciBhbmQgZmluZCB0aGUgaW1tZWRpYXRlIGRlY29tcG9zZWQgY2hhcmFjdGVyIGJlZm9yZSB0aGUgbWF0Y2ggdG8gCgkqIHNlZSBpZiBpdCBpcyBhbiBub24taWdub3JhYmxlIGFjY2VudC4KCSogTm93IG5vcm1hbGl6aW5nIHRoZSBmaXJzdCBjb21wb3NpdGUgY2hhcmFjdGVyIGlzIGVub3VnaCBiZWNhdXNlIHdlIGVuc3VyZSAKCSogdGhhdCB3aGVuIHRoZSBtYXRjaCBpcyBwYXNzZWQgaW4gaGVyZSB3aXRoIGV4dHJhIGJlZ2lubmluZyBjZXMsIHRoZSAKCSogZmlyc3Qgb3IgbGFzdCBjZSB0aGF0IG1hdGNoIGhhcyB0byBvY2N1ciB3aXRoaW4gdGhlIGZpcnN0IGNoYXJhY3Rlci4KCSogRS5nLiBsb29raW5nIGZvciBcdTAzMDEgYWN1dGUgaW4gXHUwMUZBIEEgcmluZyBhYm92ZSBhbmQgYWN1dGUsIAoJKiBjaGVja0V4dHJhTWF0Y2hBY2NlbnQgc2hvdWxkIGZhaWwgc2luY2UgdGhlcmUgaXMgYSBtaWRkbGUgcmluZyBpbiBcdTAxRkEKCSogTm90ZSBoZXJlIHRoYXQgYWNjZW50cyBjaGVja2luZyBhcmUgc2xvdyBhbmQgY2F1dGlvbmVkIGluIHRoZSBBUEkgZG9jcy4KCSogQHBhcmFtIHN0YXJ0IG9mZnNldCAKCSogQHBhcmFtIGVuZCBvZmZzZXQKCSogQHJldHVybiB0cnVlIGlmIHRoZXJlIGFyZSBhY2NlbnRzIG9uIGVpdGhlciBzaWRlIG9mIHRoZSBtYXRjaCwgCgkqICAgICAgICAgZmFsc2Ugb3RoZXJ3aXNlCgkqLwoJcHJpdmF0ZSBmaW5hbCBib29sZWFuIGhhc0FjY2VudHNCZWZvcmVNYXRjaChpbnQgc3RhcnQsIGludCBlbmQpIAoJewoJICAgIGlmIChtX3BhdHRlcm5fLm1faGFzUHJlZml4QWNjZW50c18pIHsKCSAgICAgICAgLy8gd2UgaGF2ZSBiZWVuIGl0ZXJhdGluZyBmb3J3YXJkcyBwcmV2aW91c2x5CgkgICAgICAgIGJvb2xlYW4gaWdub3JhYmxlID0gdHJ1ZTsKCSAgICAgICAgaW50IGZpcnN0Y2UgPSBtX3BhdHRlcm5fLm1fQ0VfWzBdOwoJCQltX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldChzdGFydCk7CgkgICAgICAgIGludCBjZSAgPSBnZXRDRShtX2NvbEVJdGVyXy5uZXh0KCkpOwoJICAgICAgICB3aGlsZSAoY2UgIT0gZmlyc3RjZSkgewoJICAgICAgICAgICAgaWYgKGNlICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgICAgICBpZ25vcmFibGUgPSBmYWxzZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGNlID0gZ2V0Q0UobV9jb2xFSXRlcl8ubmV4dCgpKTsKCSAgICAgICAgfQoJICAgICAgICBpZiAoIWlnbm9yYWJsZSAmJiBtX2NvbEVJdGVyXy5pc0luQnVmZmVyKCkpIHsKCSAgICAgICAgICAgIC8vIHdpdGhpbiBub3JtYWxpemF0aW9uIGJ1ZmZlciwgZGlzY29udGlndW91cyBoYW5kbGVkIGhlcmUKCSAgICAgICAgICAgIHJldHVybiB0cnVlOwoJICAgICAgICB9CgkKCSAgICAgICAgLy8gd2l0aGluIHRleHQKCSAgICAgICAgYm9vbGVhbiBhY2NlbnQgPSAoZ2V0RkNEKHRhcmdldFRleHQsIHN0YXJ0KSA+PiBTRUNPTkRfTEFTVF9CWVRFX1NISUZUXykKCSAgICAgICAgCQkJCQkJCQkJCQkhPSAwOyAKCSAgICAgICAgaWYgKCFhY2NlbnQpIHsKCSAgICAgICAgICAgIHJldHVybiBjaGVja0V4dHJhTWF0Y2hBY2NlbnRzKHN0YXJ0LCBlbmQpOwoJICAgICAgICB9CgkgICAgICAgIGlmICghaWdub3JhYmxlKSB7CgkgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCSAgICAgICAgfQoJICAgICAgICBpZiAoc3RhcnQgPiBtX3RleHRCZWdpbk9mZnNldF8pIHsKCSAgICAgICAgCXRhcmdldFRleHQuc2V0SW5kZXgoc3RhcnQpOwoJICAgICAgICAJdGFyZ2V0VGV4dC5wcmV2aW91cygpOwoJICAgICAgICAgICAgaWYgKChnZXRGQ0QodGFyZ2V0VGV4dCwgdGFyZ2V0VGV4dC5nZXRJbmRleCgpKSAmIExBU1RfQllURV9NQVNLXykgCgkgICAgICAgICAgICAJCQkJCQkJCQkJCQkJCSE9IDApIHsKCSAgICAgICAgICAgICAgICBtX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldChzdGFydCk7CgkgICAgICAgICAgICAgICAgY2UgPSBtX2NvbEVJdGVyXy5wcmV2aW91cygpOwoJICAgICAgICAgICAgICAgIGlmIChjZSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSIAoJICAgICAgICAgICAgICAgIAkmJiBjZSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CgkgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgIH0KCSAgCgkgICAgcmV0dXJuIGZhbHNlOwoJfQoJCgkvKioKCSAqIFVzZWQgYnkgZXhhY3QgbWF0Y2hlcywgY2hlY2tzIGlmIHRoZXJlIGFyZSBhY2NlbnRzIGJvdW5kaW5nIHRoZSBtYXRjaC4KCSAqIE5vdGUgdGhpcyBpcyB0aGUgaW5pdGlhbCBib3VuZGFyeSBjaGVjay4gSWYgdGhlIHBvdGVudGlhbCBtYXRjaAoJICogc3RhcnRzIG9yIGVuZHMgd2l0aCBjb21wb3NpdGUgY2hhcmFjdGVycywgdGhlIGFjY2VudHMgaW4gdGhvc2UKCSAqIGNoYXJhY3RlcnMgd2lsbCBiZSBkZXRlcm1pbmVkIGxhdGVyLgoJICogTm90IGRvaW5nIGJhY2t3YXJkcyBpdGVyYXRpb24gaGVyZSwgc2luY2UgZGlzY29udGlndW9zIGNvbnRyYWN0aW9uIGZvciAKCSAqIGJhY2t3YXJkcyBjb2xsYXRpb24gZWxlbWVudCBpdGVyYXRvciwgdXNlIHVwIHRvbyBtYW55IGNoYXJhY3RlcnMuCgkgKiBFLmcuIGxvb2tpbmcgZm9yIFx1MDMwQSByaW5nIGluIFx1MDFGQSBBIHJpbmcgYWJvdmUgYW5kIGFjdXRlLCAKCSAqIHNob3VsZCBmYWlsIHNpbmNlIHRoZXJlIGlzIGEgYWN1dGUgYXQgdGhlIGVuZCBvZiBcdTAxRkEKCSAqIE5vdGUgaGVyZSB0aGF0IGFjY2VudHMgY2hlY2tpbmcgYXJlIHNsb3cgYW5kIGNhdXRpb25lZCBpbiB0aGUgQVBJIGRvY3MuCgkgKiBAcGFyYW0gc3RhcnQgb2Zmc2V0IG9mIG1hdGNoCgkgKiBAcGFyYW0gZW5kIGVuZCBvZmZzZXQgb2YgdGhlIG1hdGNoCgkgKiBAcmV0dXJuIHRydWUgaWYgdGhlcmUgYXJlIGFjY2VudHMgb24gZWl0aGVyIHNpZGUgb2YgdGhlIG1hdGNoLCAKCSAqICAgICAgICAgZmFsc2Ugb3RoZXJ3aXNlCgkgKi8KCXByaXZhdGUgZmluYWwgYm9vbGVhbiBoYXNBY2NlbnRzQWZ0ZXJNYXRjaChpbnQgc3RhcnQsIGludCBlbmQpIAoJewoJICAgIGlmIChtX3BhdHRlcm5fLm1faGFzU3VmZml4QWNjZW50c18pIHsKCSAgICAJdGFyZ2V0VGV4dC5zZXRJbmRleChlbmQpOwoJICAgICAgICBpZiAoZW5kID4gbV90ZXh0QmVnaW5PZmZzZXRfIAoJICAgICAgICAJJiYgVVRGMTYuaXNUcmFpbFN1cnJvZ2F0ZSh0YXJnZXRUZXh0LnByZXZpb3VzKCkpKSB7CgkgICAgICAgIAlpZiAodGFyZ2V0VGV4dC5nZXRJbmRleCgpID4gbV90ZXh0QmVnaW5PZmZzZXRfICYmCgkgICAgICAgIAkJIVVURjE2LmlzTGVhZFN1cnJvZ2F0ZSh0YXJnZXRUZXh0LnByZXZpb3VzKCkpKSB7CgkgICAgICAgIAkJdGFyZ2V0VGV4dC5uZXh0KCk7CgkgICAgICAgIAl9CgkgICAgICAgIH0KCSAgICAgICAgaWYgKChnZXRGQ0QodGFyZ2V0VGV4dCwgdGFyZ2V0VGV4dC5nZXRJbmRleCgpKSAmIExBU1RfQllURV9NQVNLXykgIT0gMCkgewoJICAgICAgICAgICAgaW50IGZpcnN0Y2UgID0gbV9wYXR0ZXJuXy5tX0NFX1swXTsKCSAgICAgICAgICAgIG1fY29sRUl0ZXJfLnNldEV4YWN0T2Zmc2V0KHN0YXJ0KTsKCSAgICAgICAgICAgIHdoaWxlIChnZXRDRShtX2NvbEVJdGVyXy5uZXh0KCkpICE9IGZpcnN0Y2UpIHsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGludCBjb3VudCA9IDE7CgkgICAgICAgICAgICB3aGlsZSAoY291bnQgPCBtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfKSB7CgkgICAgICAgICAgICAgICAgaWYgKGdldENFKG1fY29sRUl0ZXJfLm5leHQoKSkgCgkgICAgICAgICAgICAgICAgCT09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgICAgICAJY291bnQgLS07CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgIGNvdW50ICsrOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaW50IGNlID0gZ2V0Q0UobV9jb2xFSXRlcl8ubmV4dCgpKTsKCSAgICAgICAgICAgIGlmIChjZSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSIAoJICAgICAgICAgICAgCQkJJiYgY2UgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgICAgIGlmIChtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKSA8PSBlbmQpIHsKCSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgIGlmICgoZ2V0RkNEKHRhcmdldFRleHQsIGVuZCkgPj4gU0VDT05EX0xBU1RfQllURV9TSElGVF8pIAoJICAgICAgICAgICAgICAgIAkhPSAwKSB7CgkgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgIH0KCSAgICByZXR1cm4gZmFsc2U7Cgl9CgkKCS8qKgoJKiBDaGVja3MgaWYgdGhlIG9mZnNldCBydW5zIG91dCBvZiB0aGUgdGV4dCBzdHJpbmcgcmFuZ2UKCSogQHBhcmFtIHRleHRzdGFydCBvZmZzZXQgb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgcmFuZ2UKCSogQHBhcmFtIHRleHRsaW1pdCBsaW1pdCBvZmZzZXQgb2YgdGhlIHRleHQgc3RyaW5nIHJhbmdlCgkqIEBwYXJhbSBvZmZzZXQgdG8gdGVzdAoJKiBAcmV0dXJuIHRydWUgaWYgb2Zmc2V0IGlzIG91dCBvZiBib3VuZHMsIGZhbHNlIG90aGVyd2lzZQoJKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gaXNPdXRPZkJvdW5kcyhpbnQgdGV4dHN0YXJ0LCBpbnQgdGV4dGxpbWl0LCAKCQkJCQkJCQkJCQkJaW50IG9mZnNldCkKCXsKCSAgICByZXR1cm4gb2Zmc2V0IDwgdGV4dHN0YXJ0IHx8IG9mZnNldCA+IHRleHRsaW1pdDsKCX0KCQoJLyoqCgkgKiBDaGVja3MgZm9yIGlkZW50aWNhbCBtYXRjaAoJICogQHBhcmFtIHN0cnNyY2ggc3RyaW5nIHNlYXJjaCBkYXRhCgkgKiBAcGFyYW0gc3RhcnQgb2Zmc2V0IG9mIHBvc3NpYmxlIG1hdGNoCgkgKiBAcGFyYW0gZW5kIG9mZnNldCBvZiBwb3NzaWJsZSBtYXRjaAoJICogQHJldHVybiB0cnVlIGlmIGlkZW50aWNhbCBtYXRjaCBpcyBmb3VuZAoJICovCglwcml2YXRlIGZpbmFsIGJvb2xlYW4gY2hlY2tJZGVudGljYWwoaW50IHN0YXJ0LCBpbnQgZW5kKSAKCXsKCSAgICBpZiAobV9jb2xsYXRvcl8uZ2V0U3RyZW5ndGgoKSAhPSBDb2xsYXRvci5JREVOVElDQUwpIHsKCSAgICAgICAgcmV0dXJuIHRydWU7CgkgICAgfQoJCgkJU3RyaW5nIHRleHRzdHIgPSBnZXRTdHJpbmcodGFyZ2V0VGV4dCwgc3RhcnQsIGVuZCAtIHN0YXJ0KTsKCQlpZiAoTm9ybWFsaXplci5xdWlja0NoZWNrKHRleHRzdHIsIE5vcm1hbGl6ZXIuTkZEKSAKCSAgICAgICAgCQkJCQkJCQkJCT09IE5vcm1hbGl6ZXIuTk8pIHsKCSAgICAgICAgdGV4dHN0ciA9IE5vcm1hbGl6ZXIuZGVjb21wb3NlKHRleHRzdHIsIGZhbHNlKTsKCSAgICB9CgkgICAgU3RyaW5nIHBhdHRlcm5zdHIgPSBtX3BhdHRlcm5fLnRhcmdldFRleHQ7CgkgICAgaWYgKE5vcm1hbGl6ZXIucXVpY2tDaGVjayhwYXR0ZXJuc3RyLCBOb3JtYWxpemVyLk5GRCkgCgkgICAgICAgIAkJCQkJCQkJCQk9PSBOb3JtYWxpemVyLk5PKSB7CgkgICAgICAgIHBhdHRlcm5zdHIgPSBOb3JtYWxpemVyLmRlY29tcG9zZShwYXR0ZXJuc3RyLCBmYWxzZSk7CgkgICAgfQoJICAgIHJldHVybiB0ZXh0c3RyLmVxdWFscyhwYXR0ZXJuc3RyKTsKCX0KCQoJLyoqCgkgKiBDaGVja3MgdG8gc2VlIGlmIHRoZSBtYXRjaCBpcyByZXBlYXRlZAoJICogQHBhcmFtIHN0YXJ0IG5ldyBtYXRjaCBzdGFydCBpbmRleAoJICogQHBhcmFtIGxpbWl0IG5ldyBtYXRjaCBsaW1pdCBpbmRleAoJICogQHJldHVybiB0cnVlIGlmIHRoZSB0aGUgbWF0Y2ggaXMgcmVwZWF0ZWQsIGZhbHNlIG90aGVyd2lzZQoJICovCglwcml2YXRlIGZpbmFsIGJvb2xlYW4gY2hlY2tSZXBlYXRlZE1hdGNoKGludCBzdGFydCwgaW50IGxpbWl0KQoJewoJICAgIGlmIChtX21hdGNoZWRJbmRleF8gPT0gRE9ORSkgewoJICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgfQogICAgICAgIGludCBlbmQgPSBsaW1pdCAtIDE7IC8vIGxhc3QgY2hhcmFjdGVyIGluIHRoZSBtYXRjaAoJICAgIGludCBsYXN0bWF0Y2hlbmQgPSBtX21hdGNoZWRJbmRleF8gKyBtYXRjaExlbmd0aCAtIDE7IAoJICAgIGlmICghaXNPdmVybGFwcGluZygpKSB7CiAgICAgICAgICAgIHJldHVybiAoc3RhcnQgPj0gbV9tYXRjaGVkSW5kZXhfICYmIHN0YXJ0IDw9IGxhc3RtYXRjaGVuZCkgCiAgICAgICAgICAgICAgICAgICAgfHwgKGVuZCA+PSBtX21hdGNoZWRJbmRleF8gJiYgZW5kIDw9IGxhc3RtYXRjaGVuZCk7CiAgICAgICAgICAgICAgICAgICAgICAKCSAgICB9CgkgICAgcmV0dXJuIHN0YXJ0ID09IG1fbWF0Y2hlZEluZGV4XzsKCX0KCQoJLyoqCgkgKiBDaGVja3MgbWF0Y2ggZm9yIGNvbnRyYWN0aW9uLiAKCSAqIElmIHRoZSBtYXRjaCBlbmRzIHdpdGggYSBwYXJ0aWFsIGNvbnRyYWN0aW9uIHdlIGZhaWwuCgkgKiBJZiB0aGUgbWF0Y2ggc3RhcnRzIHRvbyBmYXIgb2ZmIChiZWNhdXNlIG9mIGJhY2t3YXJkcyBpdGVyYXRpb24pIHdlIHRyeSAKCSAqIHRvIGNoaXAgb2ZmIHRoZSBleHRyYSBjaGFyYWN0ZXJzIGRlcGVuZGluZyBvbiB3aGV0aGVyIGEgYnJlYWtpdGVyYXRvciAKCSAqIGhhcyBiZWVuIHVzZWQuCgkgKiBUZW1wb3JhcnkgdXRpbGl0eSBidWZmZXIgdXNlZCB0byByZXR1cm4gbW9kaWZpZWQgc3RhcnQgYW5kIGVuZC4KCSAqIEBwYXJhbSBzdGFydCBvZmZzZXQgb2YgcG90ZW50aWFsIG1hdGNoLCB0byBiZSBtb2RpZmllZCBpZiBuZWNlc3NhcnkKCSAqIEBwYXJhbSBlbmQgb2Zmc2V0IG9mIHBvdGVudGlhbCBtYXRjaCwgdG8gYmUgbW9kaWZpZWQgaWYgbmVjZXNzYXJ5CgkgKiBAcmV0dXJuIHRydWUgaWYgbWF0Y2ggcGFzc2VzIHRoZSBjb250cmFjdGlvbiB0ZXN0LCBmYWxzZSBvdGhlcndpc2UuCgkgKi8KCXByaXZhdGUgZmluYWwgYm9vbGVhbiBjaGVja05leHRFeGFjdENvbnRyYWN0aW9uTWF0Y2goaW50IHN0YXJ0LCBpbnQgZW5kKSAKCXsKCSAgICAvLyBUaGlzIHBhcnQgY2hlY2tzIGlmIGVpdGhlciBlbmRzIG9mIHRoZSBtYXRjaCBjb250YWlucyBwb3RlbnRpYWwgCgkgICAgLy8gY29udHJhY3Rpb24uIElmIHNvIHdlJ2xsIGhhdmUgdG8gaXRlcmF0ZSB0aHJvdWdoIHRoZW0KCSAgICBjaGFyIGVuZGNoYXIgPSAwOwoJICAgIGlmIChlbmQgPCBtX3RleHRMaW1pdE9mZnNldF8pIHsKCSAgICAJdGFyZ2V0VGV4dC5zZXRJbmRleChlbmQpOwoJICAgIAllbmRjaGFyID0gdGFyZ2V0VGV4dC5jdXJyZW50KCk7CgkgICAgfQoJICAgIGNoYXIgcG9zdHN0YXJ0Y2hhciA9IDA7CgkgICAgaWYgKHN0YXJ0ICsgMSA8IG1fdGV4dExpbWl0T2Zmc2V0XykgewoJICAgIAl0YXJnZXRUZXh0LnNldEluZGV4KHN0YXJ0ICsgMSk7CgkgICAgCXBvc3RzdGFydGNoYXIgPSB0YXJnZXRUZXh0LmN1cnJlbnQoKTsKCSAgICB9CgkgICAgaWYgKG1fY29sbGF0b3JfLmlzVW5zYWZlKGVuZGNoYXIpIAoJICAgIAl8fCBtX2NvbGxhdG9yXy5pc1Vuc2FmZShwb3N0c3RhcnRjaGFyKSkgewoJICAgICAgICAvLyBleHBhbnNpb24gcHJlZml4LCB3aGF0J3MgbGVmdCB0byBpdGVyYXRlCgkgICAgICAgIGludCBidWZmZXJlZENFT2Zmc2V0ID0gbV9jb2xFSXRlcl8ubV9DRUJ1ZmZlck9mZnNldF87CgkgICAgICAgIGJvb2xlYW4gaGFzQnVmZmVyZWRDRSA9IGJ1ZmZlcmVkQ0VPZmZzZXQgPiAwOwoJICAgICAgICBtX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldChzdGFydCk7CgkgICAgICAgIGludCB0ZW1wID0gc3RhcnQ7CgkgICAgICAgIHdoaWxlIChidWZmZXJlZENFT2Zmc2V0ID4gMCkgewoJICAgICAgICAgICAgLy8gZ2V0dGluZyByaWQgb2YgdGhlIHJlZHVuZGFudCBjZSwgY2F1c2VkIGJ5IHNldE9mZnNldC4KCSAgICAgICAgICAgIC8vIHNpbmNlIGJhY2t3YXJkIGNvbnRyYWN0aW9uL2V4cGFuc2lvbiBtYXkgaGF2ZSBleHRyYSBjZXMgaWYgCgkgICAgICAgICAgICAvLyB3ZSBhcmUgaW4gdGhlIG5vcm1hbGl6YXRpb24gYnVmZmVyLCBoYXNBY2NlbnRzQmVmb3JlTWF0Y2ggCgkgICAgICAgICAgICAvLyB3b3VsZCBoYXZlIHRha2VuIGNhcmUgb2YgaXQuCgkgICAgICAgICAgICAvLyBFLmcuIHRoZSBjaGFyYWN0ZXIgXHUwMUZBIHdpbGwgaGF2ZSBhbiBleHBhbnNpb24gb2YgMywgYnV0IAoJICAgICAgICAgICAgLy8gaWYgd2UgYXJlIG9ubHkgbG9va2luZyBmb3IgYWN1dGUgYW5kIHJpbmcgXHUwMzBBIGFuZCBcdTAzMDEsIAoJICAgICAgICAgICAgLy8gd2UnbGwgaGF2ZSB0byBza2lwIHRoZSBmaXJzdCBjZSBpbiB0aGUgZXhwYW5zaW9uIGJ1ZmZlci4KCSAgICAgICAgICAgIG1fY29sRUl0ZXJfLm5leHQoKTsKCSAgICAgICAgICAgIGlmIChtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKSAhPSB0ZW1wKSB7CgkgICAgICAgICAgICAgICAgc3RhcnQgPSB0ZW1wOwoJICAgICAgICAgICAgICAgIHRlbXAgID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBidWZmZXJlZENFT2Zmc2V0IC0tOwoJICAgICAgICB9CgkKCSAgICAgICAgaW50IGNvdW50ID0gMDsKCSAgICAgICAgd2hpbGUgKGNvdW50IDwgbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXykgewoJICAgICAgICAgICAgaW50IGNlID0gZ2V0Q0UobV9jb2xFSXRlcl8ubmV4dCgpKTsKCSAgICAgICAgICAgIGlmIChjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CgkgICAgICAgICAgICAgICAgY29udGludWU7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAoaGFzQnVmZmVyZWRDRSAmJiBjb3VudCA9PSAwIAoJICAgICAgICAgICAgCSYmIG1fY29sRUl0ZXJfLmdldE9mZnNldCgpICE9IHRlbXApIHsKCSAgICAgICAgICAgICAgICBzdGFydCA9IHRlbXA7CgkgICAgICAgICAgICAgICAgdGVtcCAgID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAoY2UgIT0gbV9wYXR0ZXJuXy5tX0NFX1tjb3VudF0pIHsKCSAgICAgICAgICAgICAgICBlbmQgKys7CgkgICAgICAgICAgICAgICAgZW5kID0gZ2V0TmV4dEJhc2VPZmZzZXQoZW5kKTsgIAoJICAgICAgICAgICAgICAgIG1fdXRpbEJ1ZmZlcl9bMF0gPSBzdGFydDsKCSAgICAgICAgICAgICAgICBtX3V0aWxCdWZmZXJfWzFdID0gZW5kOwoJICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGNvdW50ICsrOwoJICAgICAgICB9CgkgICAgfSAKCSAgICBtX3V0aWxCdWZmZXJfWzBdID0gc3RhcnQ7CgkgICAgbV91dGlsQnVmZmVyX1sxXSA9IGVuZDsKCSAgICByZXR1cm4gdHJ1ZTsKCX0KCQoJCgkvKioKCSAqIENoZWNrcyBhbmQgc2V0cyB0aGUgbWF0Y2ggaW5mb3JtYXRpb24gaWYgZm91bmQuCgkgKiBDaGVja3MgCgkgKiA8dWw+CgkgKiA8bGk+IHRoZSBwb3RlbnRpYWwgbWF0Y2ggZG9lcyBub3QgcmVwZWF0IHRoZSBwcmV2aW91cyBtYXRjaAoJICogPGxpPiBib3VuZGFyaWVzIGFyZSBjb3JyZWN0CgkgKiA8bGk+IGV4YWN0IG1hdGNoZXMgaGFzIG5vIGV4dHJhIGFjY2VudHMKCSAqIDxsaT4gaWRlbnRpY2FsIG1hdGNoZXNiCgkgKiA8bGk+IHBvdGVudGlhbCBtYXRjaCBkb2VzIG5vdCBlbmQgaW4gdGhlIG1pZGRsZSBvZiBhIGNvbnRyYWN0aW9uCgkgKiA8L3VsPgoJICogT3RoZXJ3aXNlIHRoZSBvZmZzZXQgd2lsbCBiZSBzaGlmdGVkIHRvIHRoZSBuZXh0IGNoYXJhY3Rlci4KCSAqIFRoZSByZXN1bHQgbV9tYXRjaEluZGV4XyBhbmQgbV9tYXRjaExlbmd0aF8gd2lsbCBiZSBzZXQgdG8gdGhlIHRydW5jYXRlZAoJICogbW9yZSBmaXR0aW5nIHJlc3VsdCB2YWx1ZS4KCSAqIFVzZXMgdGhlIHRlbXBvcmFyeSB1dGlsaXR5IGJ1ZmZlciBmb3Igc3RvcmluZyB0aGUgbW9kaWZpZWQgdGV4dG9mZnNldC4KCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IG9mZnNldCBpbiB0aGUgY29sbGF0aW9uIGVsZW1lbnQgdGV4dC4KCSAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbWF0Y2ggaXMgdmFsaWQsIGZhbHNlIG90aGVyd2lzZQoJICovCglwcml2YXRlIGZpbmFsIGJvb2xlYW4gY2hlY2tOZXh0RXhhY3RNYXRjaChpbnQgdGV4dG9mZnNldCkKCXsKCSAgICBpbnQgc3RhcnQgPSBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKTsgICAgICAgIAoJICAgIGlmICghY2hlY2tOZXh0RXhhY3RDb250cmFjdGlvbk1hdGNoKHN0YXJ0LCB0ZXh0b2Zmc2V0KSkgewoJICAgIAkvLyByZXR1cm5zIHRoZSBtb2RpZmllZCB0ZXh0b2Zmc2V0CgkgICAgCW1fdXRpbEJ1ZmZlcl9bMF0gPSBtX3V0aWxCdWZmZXJfWzFdOwoJICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgfQoJCgkJc3RhcnQgPSBtX3V0aWxCdWZmZXJfWzBdOwoJCXRleHRvZmZzZXQgPSBtX3V0aWxCdWZmZXJfWzFdOwoJICAgIC8vIHRoaXMgdG90YWxseSBtYXRjaGVzLCBob3dldmVyIHdlIG5lZWQgdG8gY2hlY2sgaWYgaXQgaXMgcmVwZWF0aW5nCgkgICAgaWYgKCFpc0JyZWFrVW5pdChzdGFydCwgdGV4dG9mZnNldCkgCgkgICAgCXx8IGNoZWNrUmVwZWF0ZWRNYXRjaChzdGFydCwgdGV4dG9mZnNldCkgCgkgICAgCXx8IGhhc0FjY2VudHNCZWZvcmVNYXRjaChzdGFydCwgdGV4dG9mZnNldCkgCgkgICAgCXx8ICFjaGVja0lkZW50aWNhbChzdGFydCwgdGV4dG9mZnNldCkgCgkgICAgCXx8IGhhc0FjY2VudHNBZnRlck1hdGNoKHN0YXJ0LCB0ZXh0b2Zmc2V0KSkgewoJICAgICAgICB0ZXh0b2Zmc2V0ICsrOwoJICAgICAgICB0ZXh0b2Zmc2V0ID0gZ2V0TmV4dEJhc2VPZmZzZXQodGV4dG9mZnNldCk7ICAKCSAgICAgICAgbV91dGlsQnVmZmVyX1swXSA9IHRleHRvZmZzZXQ7CgkgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICB9CgkgICAgICAgIAoJICAgIC8vIHRvdGFsbHkgbWF0Y2gsIHdlIHdpbGwgZ2V0IHJpZCBvZiB0aGUgZW5kaW5nIGlnbm9yYWJsZXMuCgkgICAgbV9tYXRjaGVkSW5kZXhfICA9IHN0YXJ0OwoJICAgIG1hdGNoTGVuZ3RoID0gdGV4dG9mZnNldCAtIHN0YXJ0OwoJICAgIHJldHVybiB0cnVlOwoJfQoJCgkvKioKCSogR2V0dGluZyB0aGUgcHJldmlvdXMgYmFzZSBjaGFyYWN0ZXIgb2Zmc2V0LCBvciB0aGUgY3VycmVudCBvZmZzZXQgaWYgdGhlIAoJKiBjdXJyZW50IGNoYXJhY3RlciBpcyBhIGJhc2UgY2hhcmFjdGVyCgkqIEBwYXJhbSB0ZXh0IHRoZSBzb3VyY2UgdGV4dCB0byB3b3JrIG9uCgkqIEBwYXJhbSB0ZXh0b2Zmc2V0IG9uZSBvZmZzZXQgYWZ0ZXIgdGhlIGN1cnJlbnQgY2hhcmFjdGVyCgkqIEByZXR1cm4gdGhlIG9mZnNldCBvZiB0aGUgbmV4dCBjaGFyYWN0ZXIgYWZ0ZXIgdGhlIGJhc2UgY2hhcmFjdGVyIG9yIHRoZSAKCSogCQkJZmlyc3QgY29tcG9zZWQgY2hhcmFjdGVyIHdpdGggYWNjZW50cwoJKi8KCXByaXZhdGUgZmluYWwgaW50IGdldFByZXZpb3VzQmFzZU9mZnNldChDaGFyYWN0ZXJJdGVyYXRvciB0ZXh0LCAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdGV4dG9mZnNldCkKCXsKCSAgICBpZiAodGV4dG9mZnNldCA+IG1fdGV4dEJlZ2luT2Zmc2V0XykgewoJICAgICAgICB3aGlsZSAodHJ1ZSkgewoJICAgICAgICAgICAgaW50IHJlc3VsdCA9IHRleHRvZmZzZXQ7CgkgICAgICAgICAgICB0ZXh0LnNldEluZGV4KHJlc3VsdCk7CgkgICAgICAgICAgICBpZiAoVVRGMTYuaXNUcmFpbFN1cnJvZ2F0ZSh0ZXh0LnByZXZpb3VzKCkpKSB7CgkgICAgICAgICAgICAJaWYgKHRleHQuZ2V0SW5kZXgoKSAhPSB0ZXh0LmdldEJlZ2luSW5kZXgoKSAmJgoJICAgICAgICAgICAgCQkhVVRGMTYuaXNMZWFkU3Vycm9nYXRlKHRleHQucHJldmlvdXMoKSkpIHsKCSAgICAgICAgICAgIAkJdGV4dC5uZXh0KCk7CgkgICAgICAgICAgICAJfQoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgdGV4dG9mZnNldCA9IHRleHQuZ2V0SW5kZXgoKTsKCSAgICAgICAgICAgIGNoYXIgZmNkID0gZ2V0RkNEKHRleHQsIHRleHRvZmZzZXQpOwoJICAgICAgICAgICAgaWYgKChmY2QgPj4gU0VDT05EX0xBU1RfQllURV9TSElGVF8pID09IDApIHsKCSAgICAgICAgICAgICAgICBpZiAoKGZjZCAmIExBU1RfQllURV9NQVNLXykgIT0gMCkgewoJICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGV4dG9mZnNldDsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGlmICh0ZXh0b2Zmc2V0ID09IG1fdGV4dEJlZ2luT2Zmc2V0XykgewoJICAgICAgICAgICAgICAgIHJldHVybiBtX3RleHRCZWdpbk9mZnNldF87CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgcmV0dXJuIHRleHRvZmZzZXQ7Cgl9CgkKCS8qKgoJKiBHZXR0aW5nIHRoZSBpbmRleGVzIG9mIHRoZSBhY2NlbnRzIHRoYXQgYXJlIG5vdCBibG9ja2VkIGluIHRoZSBhcmd1bWVudAoJKiBhY2NlbnQgYXJyYXkKCSogQHBhcmFtIGFjY2VudHMgYWNjZW50cyBpbiBuZmQuCgkqIEBwYXJhbSBhY2NlbnRzaW5kZXggYXJyYXkgdG8gc3RvcmUgdGhlIGluZGV4ZXMgb2YgYWNjZW50cyBpbiBhY2NlbnRzIHRoYXQgCgkqIAkJYXJlIG5vdCBibG9ja2VkCgkqIEByZXR1cm4gdGhlIGxlbmd0aCBvZiBwb3B1bGF0ZWQgYWNjZW50c2luZGV4CgkqLwoJcHJpdmF0ZSBpbnQgZ2V0VW5ibG9ja2VkQWNjZW50SW5kZXgoU3RyaW5nQnVmZmVyIGFjY2VudHMsIAoJCQkJCQkJCQkJaW50IGFjY2VudHNpbmRleFtdKQoJewoJICAgIGludCBpbmRleCA9IDA7CgkgICAgaW50IGxlbmd0aCA9IGFjY2VudHMubGVuZ3RoKCk7CgkgICAgaW50IGNjbGFzcyA9IDA7CgkgICAgaW50IHJlc3VsdCA9IDA7CgkgICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSB7CgkgICAgICAgIGludCBjb2RlcG9pbnQgPSBVVEYxNi5jaGFyQXQoYWNjZW50cywgaW5kZXgpOwoJICAgICAgICBpbnQgdGVtcGNsYXNzID0gVUNoYXJhY3Rlci5nZXRDb21iaW5pbmdDbGFzcyhjb2RlcG9pbnQpOwoJICAgICAgICBpZiAodGVtcGNsYXNzICE9IGNjbGFzcykgewoJICAgICAgICAgICAgY2NsYXNzID0gdGVtcGNsYXNzOwoJICAgICAgICAgICAgYWNjZW50c2luZGV4W3Jlc3VsdF0gPSBpbmRleDsKCSAgICAgICAgICAgIHJlc3VsdCArKzsKCSAgICAgICAgfQoJICAgICAgICBpZiAoVUNoYXJhY3Rlci5pc1N1cHBsZW1lbnRhcnkoY29kZXBvaW50KSkgewoJICAgICAgICAJaW5kZXggKz0gMjsKCSAgICAgICAgfQoJICAgICAgICBlbHNlIHsKCSAgICAgICAgCWluZGV4ICsrOwoJICAgICAgICB9CgkgICAgfQoJICAgIGFjY2VudHNpbmRleFtyZXN1bHRdID0gbGVuZ3RoOwoJICAgIHJldHVybiByZXN1bHQ7Cgl9CgoJLyoqCgkgKiBBcHBlbmRzIDMgU3RyaW5nQnVmZmVyL0NoYXJhY3Rlckl0ZXJhdG9yIHRvZ2V0aGVyIGludG8gYSBkZXN0aW5hdGlvbiAKCSAqIHN0cmluZyBidWZmZXIuCgkgKiBAcGFyYW0gc291cmNlMSBzdHJpbmcgYnVmZmVyCgkgKiBAcGFyYW0gc291cmNlMiBjaGFyYWN0ZXIgaXRlcmF0b3IKCSAqIEBwYXJhbSBzdGFydDIgc3RhcnQgb2YgdGhlIGNoYXJhY3RlciBpdGVyYXRvciB0byBtZXJnZQoJICogQHBhcmFtIGVuZDIgZW5kIG9mIHRoZSBjaGFyYWN0ZXIgaXRlcmF0b3IgdG8gbWVyZ2UKCSAqIEBwYXJhbSBzb3VyY2UzIHN0cmluZyBidWZmZXIKCSAqIEByZXR1cm4gYXBwZW5kZWQgc3RyaW5nIGJ1ZmZlcgoJICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdCdWZmZXIgbWVyZ2UoU3RyaW5nQnVmZmVyIHNvdXJjZTEsIAoJCQkJCQkJCQkgCQlDaGFyYWN0ZXJJdGVyYXRvciBzb3VyY2UyLAoJCQkJCQkJCQkgCQlpbnQgc3RhcnQyLCBpbnQgZW5kMiwKCQkJCQkJCQkJIAkJU3RyaW5nQnVmZmVyIHNvdXJjZTMpIAoJewoJCVN0cmluZ0J1ZmZlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CQoJCWlmIChzb3VyY2UxICE9IG51bGwgJiYgc291cmNlMS5sZW5ndGgoKSAhPSAwKSB7CgkJCXJlc3VsdC5hcHBlbmQoc291cmNlMSk7CgkJfQoJCXNvdXJjZTIuc2V0SW5kZXgoc3RhcnQyKTsKCQl3aGlsZSAoc291cmNlMi5nZXRJbmRleCgpIDwgZW5kMikgewoJCQlyZXN1bHQuYXBwZW5kKHNvdXJjZTIuY3VycmVudCgpKTsKCQkJc291cmNlMi5uZXh0KCk7CgkJfQoJCWlmIChzb3VyY2UzICE9IG51bGwgJiYgc291cmNlMy5sZW5ndGgoKSAhPSAwKSB7CgkJCXJlc3VsdC5hcHBlbmQoc291cmNlMyk7CgkJfQoJICAgIHJldHVybiByZXN1bHQ7Cgl9CgkKCS8qKgoJKiBSdW5uaW5nIHRocm91Z2ggYSBjb2xsYXRpb24gZWxlbWVudCBpdGVyYXRvciB0byBzZWUgaWYgdGhlIGNvbnRlbnRzIAoJKiBtYXRjaGVzIHBhdHRlcm4gaW4gc3RyaW5nIHNlYXJjaCBkYXRhCgkqIEBwYXJhbSBjb2xlaXRlciBjb2xsYXRpb24gZWxlbWVudCBpdGVyYXRvciB0byB0ZXN0CgkqIEByZXR1cm4gdHJ1ZSBpZiBhIG1hdGNoIGlmIGZvdW5kLCBmYWxzZSBvdGhlcndpc2UKCSovCglwcml2YXRlIGZpbmFsIGJvb2xlYW4gY2hlY2tDb2xsYXRpb25NYXRjaChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgY29sZWl0ZXIpCgl7CgkgICAgaW50IHBhdHRlcm5jZWluZGV4ID0gbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXzsKCSAgICBpbnQgb2Zmc2V0ID0gMDsKCSAgICB3aGlsZSAocGF0dGVybmNlaW5kZXggPiAwKSB7CgkgICAgICAgIGludCBjZSA9IGdldENFKGNvbGVpdGVyLm5leHQoKSk7CgkgICAgICAgIGlmIChjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CgkgICAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgfQoJICAgICAgICBpZiAoY2UgIT0gbV9wYXR0ZXJuXy5tX0NFX1tvZmZzZXRdKSB7CgkgICAgICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgICAgIH0KCSAgICAgICAgb2Zmc2V0ICsrOwoJICAgICAgICBwYXR0ZXJuY2VpbmRleCAtLTsKCSAgICB9CgkgICAgcmV0dXJuIHRydWU7Cgl9CgkKCS8qKgoJICogUmVhcnJhbmdlcyB0aGUgZnJvbnQgYWNjZW50cyB0byB0cnkgbWF0Y2hpbmcuCgkgKiBQcmVmaXggYWNjZW50cyBpbiB0aGUgdGV4dCB3aWxsIGJlIGdyb3VwZWQgYWNjb3JkaW5nIHRvIHRoZWlyIGNvbWJpbmluZyAKCSAqIGNsYXNzIGFuZCB0aGUgZ3JvdXBzIHdpbGwgYmUgbWl4ZWQgYW5kIG1hdGNoZWQgdG8gdHJ5IGZpbmQgdGhlIHBlcmZlY3QgCgkgKiBtYXRjaCB3aXRoIHRoZSBwYXR0ZXJuLgoJICogU28gZm9yIGluc3RhbmNlIGxvb2tpbmcgZm9yICJcdTAzMDEiIGluICJcdTAzMEFcdTAzMDFcdTAzMjUiCgkgKiBzdGVwIDE6IHNwbGl0ICJcdTAzMEFcdTAzMDEiIGludG8gNiBvdGhlciB0eXBlIG9mIHBvdGVudGlhbCBhY2NlbnQgCgkgKiAJCSAgIHN1YnN0cmluZ3MgIlx1MDMwQSIsICJcdTAzMDEiLCAiXHUwMzI1IiwgIlx1MDMwQVx1MDMwMSIsIAoJICogCQkgICAiXHUwMzBBXHUwMzI1IiwgIlx1MDMwMVx1MDMyNSIuCgkgKiBzdGVwIDI6IGNoZWNrIGlmIGFueSBvZiB0aGUgZ2VuZXJhdGVkIHN1YnN0cmluZ3MgbWF0Y2hlcyB0aGUgcGF0dGVybi4KCSAqIEludGVybmFsIG1ldGhvZCwgc3RhdHVzIGlzIGFzc3VtZWQgdG8gYmUgc3VjY2VzcywgY2FsbGVyIGhhcyB0byBjaGVjayAKCSAqIHN0YXR1cyBiZWZvcmUgY2FsbGluZyB0aGlzIG1ldGhvZC4KCSAqIEBwYXJhbSBzdGFydCBmaXJzdCBvZmZzZXQgb2YgdGhlIGFjY2VudHMgdG8gc3RhcnQgc2VhcmNoaW5nCgkgKiBAcGFyYW0gZW5kIHN0YXJ0IG9mIHRoZSBsYXN0IGFjY2VudCBzZXQKCSAqIEByZXR1cm4gRE9ORSBpZiBhIG1hdGNoIGlzIG5vdCBmb3VuZCwgb3RoZXJ3aXNlIHJldHVybiB0aGUgc3RhcnRpbmcKCSAqICAgICAgICAgb2Zmc2V0IG9mIHRoZSBtYXRjaC4gTm90ZSB0aGlzIHN0YXJ0IGluY2x1ZGVzIGFsbCBwcmVjZWRpbmcgCgkgKiAJCSAgIGFjY2VudHMuCgkgKi8KCXByaXZhdGUgaW50IGRvTmV4dENhbm9uaWNhbFByZWZpeE1hdGNoKGludCBzdGFydCwgaW50IGVuZCkKCXsKCSAgICBpZiAoKGdldEZDRCh0YXJnZXRUZXh0LCBzdGFydCkgJiBMQVNUX0JZVEVfTUFTS18pID09IDApIHsKCSAgICAgICAgLy8gZGllLi4uIGZhaWxlZCBhdCBhIGJhc2UgY2hhcmFjdGVyCgkgICAgICAgIHJldHVybiBET05FOwoJICAgIH0KCQoJCXN0YXJ0ID0gdGFyZ2V0VGV4dC5nZXRJbmRleCgpOyAvLyBpbmRleCBjaGFuZ2VkIGJ5IGZjZAoJICAgIGludCBvZmZzZXQgPSBnZXROZXh0QmFzZU9mZnNldCh0YXJnZXRUZXh0LCBzdGFydCk7CgkgICAgc3RhcnQgPSBnZXRQcmV2aW91c0Jhc2VPZmZzZXQoc3RhcnQpOwoJCgkgICAgU3RyaW5nQnVmZmVyIGFjY2VudHMgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CgkgICAgU3RyaW5nIGFjY2VudHN0ciA9IGdldFN0cmluZyh0YXJnZXRUZXh0LCBzdGFydCwgb2Zmc2V0IC0gc3RhcnQpOwoJICAgIC8vIG5vcm1hbGl6aW5nIHRoZSBvZmZlbnNpdmUgc3RyaW5nCgkgICAgaWYgKE5vcm1hbGl6ZXIucXVpY2tDaGVjayhhY2NlbnRzdHIsIE5vcm1hbGl6ZXIuTkZEKSAKCSAgICAgICAgCQkJCQkJCQkJCT09IE5vcm1hbGl6ZXIuTk8pIHsKCSAgICAgICAgYWNjZW50c3RyID0gTm9ybWFsaXplci5kZWNvbXBvc2UoYWNjZW50c3RyLCBmYWxzZSk7CgkgICAgfQoJICAgIGFjY2VudHMuYXBwZW5kKGFjY2VudHN0cik7CgkgICAgICAgIAoJICAgIGludCBhY2NlbnRzaW5kZXhbXSA9IG5ldyBpbnRbSU5JVElBTF9BUlJBWV9TSVpFX107ICAgICAgCgkgICAgaW50IGFjY2VudHNpemUgPSBnZXRVbmJsb2NrZWRBY2NlbnRJbmRleChhY2NlbnRzLCBhY2NlbnRzaW5kZXgpOwoJICAgIGludCBjb3VudCA9ICgyIDw8IChhY2NlbnRzaXplIC0gMSkpIC0gMjsgIAoJICAgIHdoaWxlIChjb3VudCA+IDApIHsKCSAgICAJLy8gY29weSB0aGUgYmFzZSBjaGFyYWN0ZXJzCgkgICAgCW1fY2Fub25pY2FsUHJlZml4QWNjZW50c18uZGVsZXRlKDAsIAoJICAgIAkJCQkJCQkJbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5sZW5ndGgoKSk7CgkgICAgCWludCBrID0gMDsKCSAgICAgICAgZm9yICg7IGsgPCBhY2NlbnRzaW5kZXhbMF07IGsgKyspIHsKCSAgICAgICAgICAgIG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18uYXBwZW5kKGFjY2VudHMuY2hhckF0KGspKTsKCSAgICAgICAgfQoJICAgICAgICAvLyBmb3JtaW5nIGFsbCBwb3NzaWJsZSBjYW5vbmljYWwgcmVhcnJhbmdlbWVudCBieSBkcm9wcGluZwoJICAgICAgICAvLyBzZXRzIG9mIGFjY2VudHMKCSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gYWNjZW50c2l6ZSAtIDE7IGkgKyspIHsKCSAgICAgICAgICAgIGludCBtYXNrID0gMSA8PCAoYWNjZW50c2l6ZSAtIGkgLSAxKTsKCSAgICAgICAgICAgIGlmICgoY291bnQgJiBtYXNrKSAhPSAwKSB7CgkgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IGFjY2VudHNpbmRleFtpXTsgaiA8IGFjY2VudHNpbmRleFtpICsgMV07IAoJICAgICAgICAgICAgICAgIAkJCQkJCQkJCQkJCQlqICsrKSB7CgkgICAgICAgICAgICAgICAgICAgIG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18uYXBwZW5kKGFjY2VudHMuY2hhckF0KGopKTsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICAgICAgU3RyaW5nQnVmZmVyIG1hdGNoID0gbWVyZ2UobV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXywKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0VGV4dCwgb2Zmc2V0LCBlbmQsCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18pOwoJICAgICAgICAgICAgCgkgICAgICAgIC8vIGlmIHN0YXR1cyBpcyBhIGZhaWx1cmUsIHVjb2xfc2V0VGV4dCBkb2VzIG5vdGhpbmcuCgkgICAgICAgIC8vIHJ1biB0aGUgY29sbGF0b3IgaXRlcmF0b3IgdGhyb3VnaCB0aGlzIG1hdGNoCgkgICAgICAgIG1fdXRpbENvbEVJdGVyXy5zZXRUZXh0KG1hdGNoLnRvU3RyaW5nKCkpOwoJICAgICAgICBpZiAoY2hlY2tDb2xsYXRpb25NYXRjaChtX3V0aWxDb2xFSXRlcl8pKSB7CgkgICAgICAgICAJcmV0dXJuIHN0YXJ0OwoJICAgICAgICB9CgkgICAgICAgIGNvdW50IC0tOwoJICAgIH0KCSAgICByZXR1cm4gRE9ORTsKCX0KCgkvKioKCSogR2V0cyB0aGUgb2Zmc2V0IHRvIHRoZSBzYWZlIHBvaW50IGluIHRleHQgYmVmb3JlIHRleHRvZmZzZXQuCgkqIGllLiBub3QgdGhlIG1pZGRsZSBvZiBhIGNvbnRyYWN0aW9uLCBzd2FwcGFibGUgY2hhcmFjdGVycyBvciAKCSogc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzLgoJKiBAcGFyYW0gc3RhcnQgb2Zmc2V0IGluIHN0cmluZwoJKiBAcGFyYW0gdGV4dG9mZnNldCBvZmZzZXQgaW4gc3RyaW5nCgkqIEByZXR1cm4gb2Zmc2V0IHRvIHRoZSBwcmV2aW91cyBzYWZlIGNoYXJhY3RlcgoJKi8KCXByaXZhdGUgZmluYWwgaW50IGdldFByZXZpb3VzU2FmZU9mZnNldChpbnQgc3RhcnQsIGludCB0ZXh0b2Zmc2V0KQoJewoJICAgIGludCByZXN1bHQgPSB0ZXh0b2Zmc2V0OyAvLyBmaXJzdCBjb250cmFjdGlvbiBjaGFyYWN0ZXIKCSAgICB0YXJnZXRUZXh0LnNldEluZGV4KHRleHRvZmZzZXQpOwoJICAgIHdoaWxlIChyZXN1bHQgPj0gc3RhcnQgJiYgbV9jb2xsYXRvcl8uaXNVbnNhZmUodGFyZ2V0VGV4dC5wcmV2aW91cygpKSkgewoJICAgICAgICByZXN1bHQgPSB0YXJnZXRUZXh0LmdldEluZGV4KCk7CgkgICAgfQoJICAgIGlmIChyZXN1bHQgIT0gc3RhcnQpIHsKCSAgICAgICAgLy8gdGhlIGZpcnN0IGNvbnRyYWN0aW9uIGNoYXJhY3RlciBpcyBjb25zaWRlciB1bnNhZmUgaGVyZQoJICAgICAgICByZXN1bHQgPSB0YXJnZXRUZXh0LmdldEluZGV4KCk7IC8vIG9yaWdpbmFsbHkgcmVzdWx0IC0tOwoJICAgIH0KCSAgICByZXR1cm4gcmVzdWx0OyAKCX0KCgkvKioKCSAqIFRha2UgdGhlIHJlYXJyYW5nZWQgZW5kIGFjY2VudHMgYW5kIHRyaWVzIG1hdGNoaW5nLiBJZiBtYXRjaCBmYWlsZWQgYXQKCSAqIGEgc2VwZXJhdGUgcHJlY2VkaW5nIHNldCBvZiBhY2NlbnRzIChzZXBlcmF0ZWQgZnJvbSB0aGUgcmVhcnJhbmdlZCBvbiBieQoJICogYXQgbGVhc3QgYSBiYXNlIGNoYXJhY3RlcikgdGhlbiB3ZSByZWFycmFuZ2UgdGhlIHByZWNlZGluZyBhY2NlbnRzIGFuZCAKCSAqIHRyaWVzIG1hdGNoaW5nIGFnYWluLgoJICogV2UgYWxsb3cgc2tpcHBpbmcgb2YgdGhlIGVuZHMgb2YgdGhlIGFjY2VudCBzZXQgaWYgdGhlIGNlcyBkbyBub3QgbWF0Y2guIAoJICogSG93ZXZlciBpZiB0aGUgZmFpbHVyZSBpcyBmb3VuZCBiZWZvcmUgdGhlIGFjY2VudCBzZXQsIGl0IGZhaWxzLgoJICogSW50ZXJuYWwgbWV0aG9kLCBzdGF0dXMgYXNzdW1lZCB0byBiZSBzdWNjZXNzLCBjYWxsZXIgaGFzIHRvIGNoZWNrIAoJICogc3RhdHVzIGJlZm9yZSBjYWxsaW5nIHRoaXMgbWV0aG9kLgoJICogQHBhcmFtIHRleHRvZmZzZXQgb2YgdGhlIHN0YXJ0IG9mIHRoZSByZWFycmFuZ2VkIGFjY2VudAoJICogQHJldHVybiBET05FIGlmIGEgbWF0Y2ggaXMgbm90IGZvdW5kLCBvdGhlcndpc2UgcmV0dXJuIHRoZSBzdGFydGluZwoJICogICAgICAgICBvZmZzZXQgb2YgdGhlIG1hdGNoLiBOb3RlIHRoaXMgc3RhcnQgaW5jbHVkZXMgYWxsIHByZWNlZGluZyAKCSAqICAgICAgICAgYWNjZW50cy4KCSAqLwoJcHJpdmF0ZSBpbnQgZG9OZXh0Q2Fub25pY2FsU3VmZml4TWF0Y2goaW50IHRleHRvZmZzZXQpCgl7CgkgICAgaW50IHNhZmVsZW5ndGggPSAwOwoJICAgIFN0cmluZ0J1ZmZlciBzYWZldGV4dDsKCQlpbnQgc2FmZW9mZnNldCA9IG1fdGV4dEJlZ2luT2Zmc2V0XzsgCgkJCgkgICAgaWYgKHRleHRvZmZzZXQgIT0gbV90ZXh0QmVnaW5PZmZzZXRfIAoJICAgIAkmJiBtX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfLmxlbmd0aCgpID4gMAoJICAgIAkmJiBtX2NvbGxhdG9yXy5pc1Vuc2FmZShtX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfLmNoYXJBdCgwKSkpIHsKCSAgICAgICAgc2FmZW9mZnNldCAgICAgPSBnZXRQcmV2aW91c1NhZmVPZmZzZXQobV90ZXh0QmVnaW5PZmZzZXRfLCAKCSAgICAgICAgCQkJCQkJCQkJCXRleHRvZmZzZXQpOwoJICAgICAgICBzYWZlbGVuZ3RoICAgICA9IHRleHRvZmZzZXQgLSBzYWZlb2Zmc2V0OwoJICAgICAgICBzYWZldGV4dCAgICAgICA9IG1lcmdlKG51bGwsIHRhcmdldFRleHQsIHNhZmVvZmZzZXQsIHRleHRvZmZzZXQsIAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18pOwoJICAgIH0KCSAgICBlbHNlIHsKCSAgICAgICAgc2FmZXRleHQgPSBtX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfOwoJICAgIH0KCQoJICAgIC8vIGlmIHN0YXR1cyBpcyBhIGZhaWx1cmUsIHVjb2xfc2V0VGV4dCBkb2VzIG5vdGhpbmcKCSAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgY29sZWl0ZXIgPSBtX3V0aWxDb2xFSXRlcl87CgkgICAgY29sZWl0ZXIuc2V0VGV4dChzYWZldGV4dC50b1N0cmluZygpKTsKCSAgICAvLyBzdGF0dXMgY2hlY2tlZCBpbiBsb29wIGJlbG93CgkKCSAgICBpbnQgY2VpbmRleCA9IG1fcGF0dGVybl8ubV9DRUxlbmd0aF8gLSAxOwoJICAgIGJvb2xlYW4gaXNTYWZlID0gdHJ1ZTsgLy8gaW5kaWNhdGlvbiBmbGFnIGZvciBwb3NpdGlvbiBpbiBzYWZlIHpvbmUKCSAgICAKCSAgICB3aGlsZSAoY2VpbmRleCA+PSAwKSB7CgkgICAgICAgIGludCB0ZXh0Y2UgPSBjb2xlaXRlci5wcmV2aW91cygpOwoJICAgICAgICBpZiAodGV4dGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKCSAgICAgICAgICAgIC8vIGNoZWNrIGlmIHdlIGhhdmUgcGFzc2VkIHRoZSBzYWZlIGJ1ZmZlcgoJICAgICAgICAgICAgaWYgKGNvbGVpdGVyID09IG1fY29sRUl0ZXJfKSB7CgkgICAgICAgICAgICAgICAgcmV0dXJuIERPTkU7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBjb2xlaXRlciA9IG1fY29sRUl0ZXJfOwoJICAgICAgICAgICAgaWYgKHNhZmV0ZXh0ICE9IG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18pIHsKCSAgICAgICAgICAgIAlzYWZldGV4dC5kZWxldGUoMCwgc2FmZXRleHQubGVuZ3RoKCkpOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgY29sZWl0ZXIuc2V0RXhhY3RPZmZzZXQoc2FmZW9mZnNldCk7CgkgICAgICAgICAgICAvLyBzdGF0dXMgY2hlY2tlZCBhdCB0aGUgc3RhcnQgb2YgdGhlIGxvb3AKCSAgICAgICAgICAgIGlzU2FmZSA9IGZhbHNlOwoJICAgICAgICAgICAgY29udGludWU7CgkgICAgICAgIH0KCSAgICAgICAgdGV4dGNlID0gZ2V0Q0UodGV4dGNlKTsKCSAgICAgICAgaWYgKHRleHRjZSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFIAoJICAgICAgICAJJiYgdGV4dGNlICE9IG1fcGF0dGVybl8ubV9DRV9bY2VpbmRleF0pIHsKCSAgICAgICAgICAgIC8vIGRvIHRoZSBiZWdpbm5pbmcgc3R1ZmYKCSAgICAgICAgICAgIGludCBmYWlsZWRvZmZzZXQgPSBjb2xlaXRlci5nZXRPZmZzZXQoKTsKCSAgICAgICAgICAgIGlmIChpc1NhZmUgJiYgZmFpbGVkb2Zmc2V0ID49IHNhZmVsZW5ndGgpIHsKCSAgICAgICAgICAgICAgICAvLyBhbGFzLi4uIG5vIGhvcGUuIGZhaWxlZCBhdCByZWFycmFuZ2VkIGFjY2VudCBzZXQKCSAgICAgICAgICAgICAgICByZXR1cm4gRE9ORTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGVsc2UgewoJICAgICAgICAgICAgICAgIGlmIChpc1NhZmUpIHsKCSAgICAgICAgICAgICAgICAgICAgZmFpbGVkb2Zmc2V0ICs9IHNhZmVvZmZzZXQ7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgIAoJICAgICAgICAgICAgICAgIC8vIHRyeSByZWFycmFuZ2luZyB0aGUgZnJvbnQgYWNjZW50cwoJICAgICAgICAgICAgICAgIGludCByZXN1bHQgPSBkb05leHRDYW5vbmljYWxQcmVmaXhNYXRjaChmYWlsZWRvZmZzZXQsIAoJICAgICAgICAgICAgICAgIAkJCQkJCQkJCQl0ZXh0b2Zmc2V0KTsKCSAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9IERPTkUpIHsKCSAgICAgICAgICAgICAgICAgICAgLy8gaWYgc3RhdHVzIGlzIGEgZmFpbHVyZSwgdWNvbF9zZXRPZmZzZXQgZG9lcyBub3RoaW5nCgkgICAgICAgICAgICAgICAgICAgIG1fY29sRUl0ZXJfLnNldEV4YWN0T2Zmc2V0KHJlc3VsdCk7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICAgICAgaWYgKHRleHRjZSA9PSBtX3BhdHRlcm5fLm1fQ0VfW2NlaW5kZXhdKSB7CgkgICAgICAgICAgICBjZWluZGV4IC0tOwoJICAgICAgICB9CgkgICAgfQoJICAgIC8vIHNldCBvZmZzZXQgaGVyZQoJICAgIGlmIChpc1NhZmUpIHsKCSAgICAgICAgaW50IHJlc3VsdCA9IGNvbGVpdGVyLmdldE9mZnNldCgpOwoJICAgICAgICAvLyBzZXRzIHRoZSB0ZXh0IGl0ZXJhdG9yIHdpdGggdGhlIGNvcnJlY3QgZXhwYW5zaW9uIGFuZCBvZmZzZXQKCSAgICAgICAgaW50IGxlZnRvdmVyY2VzID0gY29sZWl0ZXIubV9DRUJ1ZmZlck9mZnNldF87CgkgICAgICAgIGlmIChyZXN1bHQgPj0gc2FmZWxlbmd0aCkgeyAKCSAgICAgICAgICAgIHJlc3VsdCA9IHRleHRvZmZzZXQ7CgkgICAgICAgIH0KCSAgICAgICAgZWxzZSB7CgkgICAgICAgICAgICByZXN1bHQgKz0gc2FmZW9mZnNldDsKCSAgICAgICAgfQoJICAgICAgICBtX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldChyZXN1bHQpOwoJICAgICAgICBtX2NvbEVJdGVyXy5tX0NFQnVmZmVyT2Zmc2V0XyA9IGxlZnRvdmVyY2VzOwoJICAgICAgICByZXR1cm4gcmVzdWx0OwoJICAgIH0KCSAgICAKCSAgICByZXR1cm4gY29sZWl0ZXIuZ2V0T2Zmc2V0KCk7ICAgICAgICAgICAgICAKCX0KCQoJLyoqCgkgKiBUcnlpbmcgb3V0IHRoZSBzdWJzdHJpbmcgYW5kIHNlZXMgaWYgaXQgY2FuIGJlIGEgY2Fub25pY2FsIG1hdGNoLgoJICogVGhpcyB3aWxsIHRyeSBub3JtYWxpemluZyB0aGUgZW5kIGFjY2VudHMgYW5kIGFycmFuZ2luZyB0aGVtIGludG8gCgkgKiBjYW5vbmljYWwgZXF1aXZhbGVudHMgYW5kIGNoZWNrIHRoZWlyIGNvcnJlc3BvbmRpbmcgY2VzIHdpdGggdGhlIHBhdHRlcm4gCgkgKiBjZS4KCSAqIFN1ZmZpeCBhY2NlbnRzIGluIHRoZSB0ZXh0IHdpbGwgYmUgZ3JvdXBlZCBhY2NvcmRpbmcgdG8gdGhlaXIgY29tYmluaW5nIAoJICogY2xhc3MgYW5kIHRoZSBncm91cHMgd2lsbCBiZSBtaXhlZCBhbmQgbWF0Y2hlZCB0byB0cnkgZmluZCB0aGUgcGVyZmVjdCAKCSAqIG1hdGNoIHdpdGggdGhlIHBhdHRlcm4uCgkgKiBTbyBmb3IgaW5zdGFuY2UgbG9va2luZyBmb3IgIlx1MDMwMSIgaW4gIlx1MDMwQVx1MDMwMVx1MDMyNSIKCSAqIHN0ZXAgMTogc3BsaXQgIlx1MDMwQVx1MDMwMSIgaW50byA2IG90aGVyIHR5cGUgb2YgcG90ZW50aWFsIGFjY2VudCAKCSAqICAgICAgICAgc3Vic3RyaW5ncwoJICogICAgICAgICAiXHUwMzBBIiwgIlx1MDMwMSIsICJcdTAzMjUiLCAiXHUwMzBBXHUwMzAxIiwgIlx1MDMwQVx1MDMyNSIsIAoJICogICAgICAgICAiXHUwMzAxXHUwMzI1Ii4KCSAqIHN0ZXAgMjogY2hlY2sgaWYgYW55IG9mIHRoZSBnZW5lcmF0ZWQgc3Vic3RyaW5ncyBtYXRjaGVzIHRoZSBwYXR0ZXJuLgoJICogQHBhcmFtIHRleHRvZmZzZXQgZW5kIG9mZnNldCBpbiB0aGUgY29sbGF0aW9uIGVsZW1lbnQgdGV4dCB0aGF0IGVuZHMgd2l0aCAKCSAqICAgICAgICAgICAgICAgICAgIHRoZSBhY2NlbnRzIHRvIGJlIHJlYXJyYW5nZWQKCSAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbWF0Y2ggaXMgdmFsaWQsIGZhbHNlIG90aGVyd2lzZQoJICovCglwcml2YXRlIGJvb2xlYW4gZG9OZXh0Q2Fub25pY2FsTWF0Y2goaW50IHRleHRvZmZzZXQpCgl7CgkJaW50IG9mZnNldCA9IG1fY29sRUl0ZXJfLmdldE9mZnNldCgpOwoJCXRhcmdldFRleHQuc2V0SW5kZXgodGV4dG9mZnNldCk7CgkJaWYgKFVURjE2LmlzVHJhaWxTdXJyb2dhdGUodGFyZ2V0VGV4dC5wcmV2aW91cygpKSAKCQkJJiYgdGFyZ2V0VGV4dC5nZXRJbmRleCgpID4gbV90ZXh0QmVnaW5PZmZzZXRfKSB7IAoJCQlpZiAoIVVURjE2LmlzTGVhZFN1cnJvZ2F0ZSh0YXJnZXRUZXh0LnByZXZpb3VzKCkpKSB7CgkJCQl0YXJnZXRUZXh0Lm5leHQoKTsKCQkJfQoJCX0KCSAgICBpZiAoKGdldEZDRCh0YXJnZXRUZXh0LCB0YXJnZXRUZXh0LmdldEluZGV4KCkpICYgTEFTVF9CWVRFX01BU0tfKSA9PSAwKSB7CgkgICAgICAgIGlmIChtX3BhdHRlcm5fLm1faGFzUHJlZml4QWNjZW50c18pIHsKCSAgICAgICAgICAgIG9mZnNldCA9IGRvTmV4dENhbm9uaWNhbFByZWZpeE1hdGNoKG9mZnNldCwgdGV4dG9mZnNldCk7CgkgICAgICAgICAgICBpZiAob2Zmc2V0ICE9IERPTkUpIHsKCSAgICAgICAgICAgICAgICBtX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldChvZmZzZXQpOwoJICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICB9CgkKCSAgICBpZiAoIW1fcGF0dGVybl8ubV9oYXNTdWZmaXhBY2NlbnRzXykgewoJICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgfQoJCgkgICAgU3RyaW5nQnVmZmVyIGFjY2VudHMgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CgkgICAgLy8gb2Zmc2V0IHRvIHRoZSBsYXN0IGJhc2UgY2hhcmFjdGVyIGluIHN1YnN0cmluZyB0byBzZWFyY2gKCSAgICBpbnQgYmFzZW9mZnNldCA9IGdldFByZXZpb3VzQmFzZU9mZnNldCh0YXJnZXRUZXh0LCB0ZXh0b2Zmc2V0KTsKCSAgICAvLyBub3JtYWxpemluZyB0aGUgb2ZmZW5zaXZlIHN0cmluZwoJICAgIFN0cmluZyBhY2NlbnRzdHIgPSBnZXRTdHJpbmcodGFyZ2V0VGV4dCwgYmFzZW9mZnNldCwgCgkgICAgCQkJCQkJCSB0ZXh0b2Zmc2V0IC0gYmFzZW9mZnNldCk7CgkgICAgaWYgKE5vcm1hbGl6ZXIucXVpY2tDaGVjayhhY2NlbnRzdHIsIE5vcm1hbGl6ZXIuTkZEKSAKCSAgICAgICAgCQkJCQkJCQkJCT09IE5vcm1hbGl6ZXIuTk8pIHsKCSAgICAgICAgYWNjZW50c3RyID0gTm9ybWFsaXplci5kZWNvbXBvc2UoYWNjZW50c3RyLCBmYWxzZSk7CgkgICAgfQoJICAgIGFjY2VudHMuYXBwZW5kKGFjY2VudHN0cik7CgkgICAgLy8gc3RhdHVzIGNoZWNrZWQgaW4gbG9vcCBiZWxvdwoJICAgICAgICAKCSAgICBpbnQgYWNjZW50c2luZGV4W10gPSBuZXcgaW50W0lOSVRJQUxfQVJSQVlfU0laRV9dOwoJICAgIGludCBzaXplID0gZ2V0VW5ibG9ja2VkQWNjZW50SW5kZXgoYWNjZW50cywgYWNjZW50c2luZGV4KTsKCQoJICAgIC8vIDIgcG93ZXIgbiAtIDEgbWludXMgdGhlIGZ1bGwgc2V0IG9mIGFjY2VudHMKCSAgICBpbnQgIGNvdW50ID0gKDIgPDwgKHNpemUgLSAxKSkgLSAyOyAgCgkgICAgd2hpbGUgKGNvdW50ID4gMCkgewogICAgICAgICAgICBtX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfLmRlbGV0ZSgwLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18ubGVuZ3RoKCkpOwoJICAgICAgICAvLyBjb3B5IHRoZSBiYXNlIGNoYXJhY3RlcnMKCSAgICAgICAgZm9yIChpbnQgayA9IDA7IGsgPCBhY2NlbnRzaW5kZXhbMF07IGsgKyspIHsKCSAgICAgICAgICAgIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18uYXBwZW5kKGFjY2VudHMuY2hhckF0KGspKTsKCSAgICAgICAgfQoJICAgICAgICAvLyBmb3JtaW5nIGFsbCBwb3NzaWJsZSBjYW5vbmljYWwgcmVhcnJhbmdlbWVudCBieSBkcm9wcGluZwoJICAgICAgICAvLyBzZXRzIG9mIGFjY2VudHMKCSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc2l6ZSAtIDE7IGkgKyspIHsKCSAgICAgICAgICAgIGludCBtYXNrID0gMSA8PCAoc2l6ZSAtIGkgLSAxKTsKCSAgICAgICAgICAgIGlmICgoY291bnQgJiBtYXNrKSAhPSAwKSB7CgkgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IGFjY2VudHNpbmRleFtpXTsgaiA8IGFjY2VudHNpbmRleFtpICsgMV07IAoJICAgICAgICAgICAgICAgIAlqICsrKSB7CgkgICAgICAgICAgICAgICAgICAgIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18uYXBwZW5kKGFjY2VudHMuY2hhckF0KGopKTsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICAgICAgb2Zmc2V0ID0gZG9OZXh0Q2Fub25pY2FsU3VmZml4TWF0Y2goYmFzZW9mZnNldCk7CgkgICAgICAgIGlmIChvZmZzZXQgIT0gRE9ORSkgewoJICAgICAgICAgICAgcmV0dXJuIHRydWU7IC8vIG1hdGNoIGZvdW5kCgkgICAgICAgIH0KCSAgICAgICAgY291bnQgLS07CgkgICAgfQoJICAgIHJldHVybiBmYWxzZTsKCX0KCQoJLyoqCgkgKiBHZXRzIHRoZSBwcmV2aW91cyBiYXNlIGNoYXJhY3RlciBvZmZzZXQgZGVwZW5kaW5nIG9uIHRoZSBzdHJpbmcgc2VhcmNoIAoJICogcGF0dGVybiBkYXRhCgkgKiBAcGFyYW0gc3Ryc3JjaCBzdHJpbmcgc2VhcmNoIGRhdGEKCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IGN1cnJlbnQgb2Zmc2V0LCBjdXJyZW50IGNoYXJhY3RlcgoJICogQHJldHVybiB0aGUgb2Zmc2V0IG9mIHRoZSBuZXh0IGNoYXJhY3RlciBhZnRlciB0aGlzIGJhc2UgY2hhcmFjdGVyIG9yIAoJICogCQkJaXRzZWxmIGlmIGl0IGlzIGEgY29tcG9zZWQgY2hhcmFjdGVyIHdpdGggYWNjZW50cwoJICovCglwcml2YXRlIGZpbmFsIGludCBnZXRQcmV2aW91c0Jhc2VPZmZzZXQoaW50IHRleHRvZmZzZXQpCgl7CgkgICAgaWYgKG1fcGF0dGVybl8ubV9oYXNQcmVmaXhBY2NlbnRzXyAmJiB0ZXh0b2Zmc2V0ID4gbV90ZXh0QmVnaW5PZmZzZXRfKSB7CgkgICAgICAgIGludCBvZmZzZXQgPSB0ZXh0b2Zmc2V0OwoJICAgICAgICBpZiAoKGdldEZDRCh0YXJnZXRUZXh0LCBvZmZzZXQpID4+IFNFQ09ORF9MQVNUX0JZVEVfU0hJRlRfKSAhPSAwKSB7CgkgICAgICAgICAgICByZXR1cm4gZ2V0UHJldmlvdXNCYXNlT2Zmc2V0KHRhcmdldFRleHQsIHRleHRvZmZzZXQpOwoJICAgICAgICB9CgkgICAgfQoJICAgIHJldHVybiB0ZXh0b2Zmc2V0OwoJfQoJCgkvKioKCSAqIENoZWNrcyBtYXRjaCBmb3IgY29udHJhY3Rpb24uIAoJICogSWYgdGhlIG1hdGNoIGVuZHMgd2l0aCBhIHBhcnRpYWwgY29udHJhY3Rpb24gd2UgZmFpbC4KCSAqIElmIHRoZSBtYXRjaCBzdGFydHMgdG9vIGZhciBvZmYgKGJlY2F1c2Ugb2YgYmFja3dhcmRzIGl0ZXJhdGlvbikgd2UgdHJ5IAoJICogdG8gY2hpcCBvZmYgdGhlIGV4dHJhIGNoYXJhY3RlcnMuCgkgKiBVc2VzIHRoZSB0ZW1wb3JhcnkgdXRpbCBidWZmZXIgZm9yIHJldHVybiB2YWx1ZXMgb2YgdGhlIG1vZGlmaWVkIHN0YXJ0CgkgKiBhbmQgZW5kLgoJICogQHBhcmFtIHN0YXJ0IG9mZnNldCBvZiBwb3RlbnRpYWwgbWF0Y2gsIHRvIGJlIG1vZGlmaWVkIGlmIG5lY2Vzc2FyeQoJICogQHBhcmFtIGVuZCBvZmZzZXQgb2YgcG90ZW50aWFsIG1hdGNoLCB0byBiZSBtb2RpZmllZCBpZiBuZWNlc3NhcnkKCSAqIEByZXR1cm4gdHJ1ZSBpZiBtYXRjaCBwYXNzZXMgdGhlIGNvbnRyYWN0aW9uIHRlc3QsIGZhbHNlIG90aGVyd2lzZS4gCgkgKi8KCXByaXZhdGUgYm9vbGVhbiBjaGVja05leHRDYW5vbmljYWxDb250cmFjdGlvbk1hdGNoKGludCBzdGFydCwgaW50IGVuZCkgCgl7CgkgICAgLy8gVGhpcyBwYXJ0IGNoZWNrcyBpZiBlaXRoZXIgZW5kcyBvZiB0aGUgbWF0Y2ggY29udGFpbnMgcG90ZW50aWFsIAoJICAgIC8vIGNvbnRyYWN0aW9uLiBJZiBzbyB3ZSdsbCBoYXZlIHRvIGl0ZXJhdGUgdGhyb3VnaCB0aGVtCgkgICAgY2hhciBzY2hhciA9IDA7CgkgICAgY2hhciBlY2hhciA9IDA7CgkgICAgaWYgKGVuZCA8IG1fdGV4dExpbWl0T2Zmc2V0XykgewoJICAgIAl0YXJnZXRUZXh0LnNldEluZGV4KGVuZCk7CgkgICAgCWVjaGFyID0gdGFyZ2V0VGV4dC5jdXJyZW50KCk7CgkgICAgfQoJICAgIGlmIChzdGFydCA8IG1fdGV4dExpbWl0T2Zmc2V0XykgewoJICAgIAl0YXJnZXRUZXh0LnNldEluZGV4KHN0YXJ0ICsgMSk7CgkgICAgCXNjaGFyID0gdGFyZ2V0VGV4dC5jdXJyZW50KCk7CgkgICAgfQoJICAgIGlmIChtX2NvbGxhdG9yXy5pc1Vuc2FmZShlY2hhcikgfHwgbV9jb2xsYXRvcl8uaXNVbnNhZmUoc2NoYXIpKSB7CgkgICAgICAgIGludCBleHBhbnNpb24gID0gbV9jb2xFSXRlcl8ubV9DRUJ1ZmZlck9mZnNldF87CgkgICAgICAgIGJvb2xlYW4gaGFzRXhwYW5zaW9uID0gZXhwYW5zaW9uID4gMDsKCSAgICAgICAgbV9jb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQoc3RhcnQpOwoJICAgICAgICBpbnQgdGVtcCA9IHN0YXJ0OwoJICAgICAgICB3aGlsZSAoZXhwYW5zaW9uID4gMCkgewoJICAgICAgICAgICAgLy8gZ2V0dGluZyByaWQgb2YgdGhlIHJlZHVuZGFudCBjZSwgY2F1c2VkIGJ5IHNldE9mZnNldC4KCSAgICAgICAgICAgIC8vIHNpbmNlIGJhY2t3YXJkIGNvbnRyYWN0aW9uL2V4cGFuc2lvbiBtYXkgaGF2ZSBleHRyYSBjZXMgaWYgCgkgICAgICAgICAgICAvLyB3ZSBhcmUgaW4gdGhlIG5vcm1hbGl6YXRpb24gYnVmZmVyLCBoYXNBY2NlbnRzQmVmb3JlTWF0Y2ggCgkgICAgICAgICAgICAvLyB3b3VsZCBoYXZlIHRha2VuIGNhcmUgb2YgaXQuCgkgICAgICAgICAgICAvLyBFLmcuIHRoZSBjaGFyYWN0ZXIgXHUwMUZBIHdpbGwgaGF2ZSBhbiBleHBhbnNpb24gb2YgMywgYnV0IAoJICAgICAgICAgICAgLy8gaWYgd2UgYXJlIG9ubHkgbG9va2luZyBmb3IgYWN1dGUgYW5kIHJpbmcgXHUwMzBBIGFuZCBcdTAzMDEsIAoJICAgICAgICAgICAgLy8gd2UnbGwgaGF2ZSB0byBza2lwIHRoZSBmaXJzdCBjZSBpbiB0aGUgZXhwYW5zaW9uIGJ1ZmZlci4KCSAgICAgICAgICAgIG1fY29sRUl0ZXJfLm5leHQoKTsKCSAgICAgICAgICAgIGlmIChtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKSAhPSB0ZW1wKSB7CgkgICAgICAgICAgICAgICAgc3RhcnQgPSB0ZW1wOwoJICAgICAgICAgICAgICAgIHRlbXAgID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBleHBhbnNpb24gLS07CgkgICAgICAgIH0KCQoJICAgICAgICBpbnQgY291bnQgPSAwOwoJICAgICAgICB3aGlsZSAoY291bnQgPCBtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfKSB7CgkgICAgICAgICAgICBpbnQgY2UgPSBnZXRDRShtX2NvbEVJdGVyXy5uZXh0KCkpOwoJICAgICAgICAgICAgLy8gc3RhdHVzIGNoZWNrZWQgYmVsb3csIG5vdGUgdGhhdCBpZiBzdGF0dXMgaXMgYSBmYWlsdXJlCgkgICAgICAgICAgICAvLyB1Y29sX25leHQgcmV0dXJucyBVQ09MX05VTExPUkRFUgoJICAgICAgICAgICAgaWYgKGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGlmIChoYXNFeHBhbnNpb24gJiYgY291bnQgPT0gMCAKCSAgICAgICAgICAgIAkmJiBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKSAhPSB0ZW1wKSB7CgkgICAgICAgICAgICAgICAgc3RhcnQgPSB0ZW1wOwoJICAgICAgICAgICAgICAgIHRlbXAgPSBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKTsKCSAgICAgICAgICAgIH0KCQoJICAgICAgICAgICAgaWYgKGNvdW50ID09IDAgJiYgY2UgIT0gbV9wYXR0ZXJuXy5tX0NFX1swXSkgewoJICAgICAgICAgICAgICAgIC8vIGFjY2VudHMgbWF5IGhhdmUgZXh0cmEgc3RhcnRpbmcgY2VzLCB0aGlzIG9jY3VycyB3aGVuIGEgCgkgICAgICAgICAgICAgICAgLy8gcHVyZSBhY2NlbnQgcGF0dGVybiBpcyBtYXRjaGVkIHdpdGhvdXQgcmVhcnJhbmdlbWVudAoJICAgICAgICAgICAgICAgIC8vIHRleHQgXHUwMzI1XHUwMzAwIGFuZCBsb29raW5nIGZvciBcdTAzMDAKCSAgICAgICAgICAgICAgICBpbnQgZXhwZWN0ZWQgPSBtX3BhdHRlcm5fLm1fQ0VfWzBdOyAKCSAgICAgICAgICAgICAgICBpZiAoKGdldEZDRCh0YXJnZXRUZXh0LCBzdGFydCkgJiBMQVNUX0JZVEVfTUFTS18pICE9IDApIHsKCSAgICAgICAgICAgICAgICAgICAgY2UgPSBnZXRDRShtX2NvbEVJdGVyXy5uZXh0KCkpOwoJICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2UgIT0gZXhwZWN0ZWQgCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBjZSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSIAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCkgPD0gZW5kKSB7CgkgICAgICAgICAgICAgICAgICAgICAgICBjZSA9IGdldENFKG1fY29sRUl0ZXJfLm5leHQoKSk7CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAoY2UgIT0gbV9wYXR0ZXJuXy5tX0NFX1tjb3VudF0pIHsKCSAgICAgICAgICAgICAgICBlbmQgKys7CgkgICAgICAgICAgICAgICAgZW5kID0gZ2V0TmV4dEJhc2VPZmZzZXQoZW5kKTsgIAoJICAgICAgICAgICAgICAgIG1fdXRpbEJ1ZmZlcl9bMF0gPSBzdGFydDsKCSAgICAgICAgICAgICAgICBtX3V0aWxCdWZmZXJfWzFdID0gZW5kOwoJICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGNvdW50ICsrOwoJICAgICAgICB9CgkgICAgfSAKCSAgICBtX3V0aWxCdWZmZXJfWzBdID0gc3RhcnQ7CgkgICAgbV91dGlsQnVmZmVyX1sxXSA9IGVuZDsKCSAgICByZXR1cm4gdHJ1ZTsKCX0KCgkvKioKCSAqIENoZWNrcyBhbmQgc2V0cyB0aGUgbWF0Y2ggaW5mb3JtYXRpb24gaWYgZm91bmQuCgkgKiBDaGVja3MgCgkgKiA8dWw+CgkgKiA8bGk+IHRoZSBwb3RlbnRpYWwgbWF0Y2ggZG9lcyBub3QgcmVwZWF0IHRoZSBwcmV2aW91cyBtYXRjaAoJICogPGxpPiBib3VuZGFyaWVzIGFyZSBjb3JyZWN0CgkgKiA8bGk+IHBvdGVudGlhbCBtYXRjaCBkb2VzIG5vdCBlbmQgaW4gdGhlIG1pZGRsZSBvZiBhIGNvbnRyYWN0aW9uCgkgKiA8bGk+IGlkZW50aWNhbCBtYXRjaGVzCgkgKiA8L3VsPgoJICogT3RoZXJ3aXNlIHRoZSBvZmZzZXQgd2lsbCBiZSBzaGlmdGVkIHRvIHRoZSBuZXh0IGNoYXJhY3Rlci4KCSAqIFRoZSByZXN1bHQgbV9tYXRjaEluZGV4XyBhbmQgbV9tYXRjaExlbmd0aF8gd2lsbCBiZSBzZXQgdG8gdGhlIHRydW5jYXRlZAoJICogbW9yZSBmaXR0aW5nIHJlc3VsdCB2YWx1ZS4KCSAqIFVzZXMgdGhlIHRlbXBvcmFyeSB1dGlsaXR5IGJ1ZmZlciBmb3Igc3RvcmluZyB0aGUgbW9kaWZpZWQgdGV4dG9mZnNldC4KCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IG9mZnNldCBpbiB0aGUgY29sbGF0aW9uIGVsZW1lbnQgdGV4dC4KCSAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbWF0Y2ggaXMgdmFsaWQsIGZhbHNlIG90aGVyd2lzZQoJICovCglwcml2YXRlIGJvb2xlYW4gY2hlY2tOZXh0Q2Fub25pY2FsTWF0Y2goaW50IHRleHRvZmZzZXQpCgl7CgkgICAgLy8gdG8gZW5zdXJlIHRoYXQgdGhlIHN0YXJ0IGFuZCBlbmRzIGFyZSBub3QgY29tcG9zaXRlIGNoYXJhY3RlcnMKCSAgICAvLyBpZiB3ZSBoYXZlIGEgY2Fub25pY2FsIGFjY2VudCBtYXRjaAoJICAgIGlmICgobV9wYXR0ZXJuXy5tX2hhc1N1ZmZpeEFjY2VudHNfIAoJICAgIAkJJiYgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5sZW5ndGgoKSAhPSAwKSB8fCAKCSAgICAgICAgKG1fcGF0dGVybl8ubV9oYXNQcmVmaXhBY2NlbnRzXyAKCSAgICAgICAgCSYmIG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18ubGVuZ3RoKCkgIT0gMCkpIHsKCSAgICAgICAgbV9tYXRjaGVkSW5kZXhfID0gZ2V0UHJldmlvdXNCYXNlT2Zmc2V0KG1fY29sRUl0ZXJfLmdldE9mZnNldCgpKTsKCSAgICAgICAgbWF0Y2hMZW5ndGggPSB0ZXh0b2Zmc2V0IC0gbV9tYXRjaGVkSW5kZXhfOwoJICAgICAgICByZXR1cm4gdHJ1ZTsKCSAgICB9CgkKCSAgICBpbnQgc3RhcnQgPSBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKTsKCSAgICBpZiAoIWNoZWNrTmV4dENhbm9uaWNhbENvbnRyYWN0aW9uTWF0Y2goc3RhcnQsIHRleHRvZmZzZXQpKSB7CgkgICAgCS8vIHJldHVybiB0aGUgbW9kaWZpZWQgdGV4dG9mZnNldAoJICAgIAltX3V0aWxCdWZmZXJfWzBdID0gbV91dGlsQnVmZmVyX1sxXTsgCgkgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICB9CgkgICAgc3RhcnQgPSBtX3V0aWxCdWZmZXJfWzBdOwoJICAgIHRleHRvZmZzZXQgPSBtX3V0aWxCdWZmZXJfWzFdOwoJICAgIHN0YXJ0ID0gZ2V0UHJldmlvdXNCYXNlT2Zmc2V0KHN0YXJ0KTsKCSAgICAvLyB0aGlzIHRvdGFsbHkgbWF0Y2hlcywgaG93ZXZlciB3ZSBuZWVkIHRvIGNoZWNrIGlmIGl0IGlzIHJlcGVhdGluZwoJICAgIGlmIChjaGVja1JlcGVhdGVkTWF0Y2goc3RhcnQsIHRleHRvZmZzZXQpIAoJICAgIAl8fCAhaXNCcmVha1VuaXQoc3RhcnQsIHRleHRvZmZzZXQpIAoJICAgIAl8fCAhY2hlY2tJZGVudGljYWwoc3RhcnQsIHRleHRvZmZzZXQpKSB7CgkgICAgICAgIHRleHRvZmZzZXQgKys7CgkgICAgICAgIHRleHRvZmZzZXQgPSBnZXROZXh0QmFzZU9mZnNldCh0YXJnZXRUZXh0LCB0ZXh0b2Zmc2V0KTsKCSAgICAgICAgbV91dGlsQnVmZmVyX1swXSA9IHRleHRvZmZzZXQ7CgkgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICB9CgkgICAgCgkgICAgbV9tYXRjaGVkSW5kZXhfICA9IHN0YXJ0OwoJICAgIG1hdGNoTGVuZ3RoID0gdGV4dG9mZnNldCAtIHN0YXJ0OwoJICAgIHJldHVybiB0cnVlOwoJfQoJCgkvKioKCSAqIFNoaWZ0aW5nIHRoZSBjb2xsYXRpb24gZWxlbWVudCBpdGVyYXRvciBwb3NpdGlvbiBmb3J3YXJkIHRvIHByZXBhcmUgZm9yCgkgKiBhIHByZWNlZGluZyBtYXRjaC4gSWYgdGhlIGZpcnN0IGNoYXJhY3RlciBpcyBhIHVuc2FmZSBjaGFyYWN0ZXIsIHdlJ2xsIAoJICogb25seSBzaGlmdCBieSAxIHRvIGNhcHR1cmUgY29udHJhY3Rpb25zLCBub3JtYWxpemF0aW9uIGV0Yy4KCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IHN0YXJ0IHRleHQgcG9zaXRpb24gdG8gZG8gc2VhcmNoCgkgKiBAcGFyYW0gY2UgdGhlIHRleHQgY2Ugd2hpY2ggZmFpbGVkIHRoZSBtYXRjaC4KCSAqIEBwYXJhbSBwYXR0ZXJuY2VpbmRleCBpbmRleCBvZiB0aGUgY2Ugd2l0aGluIHRoZSBwYXR0ZXJuIGNlIGJ1ZmZlciB3aGljaAoJICogICAgICAgIGZhaWxlZCB0aGUgbWF0Y2gKCSAqIEByZXR1cm4gZmluYWwgb2Zmc2V0CgkgKi8KCXByaXZhdGUgaW50IHJldmVyc2VTaGlmdChpbnQgdGV4dG9mZnNldCwgaW50IGNlLCBpbnQgcGF0dGVybmNlaW5kZXgpCgl7ICAgICAgICAgCgkgICAgaWYgKGlzT3ZlcmxhcHBpbmcoKSkgewoJICAgICAgICBpZiAodGV4dG9mZnNldCAhPSBtX3RleHRMaW1pdE9mZnNldF8pIHsKCSAgICAgICAgICAgIHRleHRvZmZzZXQgLS07CgkgICAgICAgIH0KCSAgICAgICAgZWxzZSB7CgkgICAgICAgICAgICB0ZXh0b2Zmc2V0IC09IG1fcGF0dGVybl8ubV9kZWZhdWx0U2hpZnRTaXplXzsKCSAgICAgICAgfQoJICAgIH0KCSAgICBlbHNlIHsKCSAgICAgICAgaWYgKGNlICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKCSAgICAgICAgICAgIGludCBzaGlmdCA9IG1fcGF0dGVybl8ubV9iYWNrU2hpZnRfW2hhc2goY2UpXTsKCSAgICAgICAgICAgIAoJICAgICAgICAgICAgLy8gdGhpcyBpcyB0byBhZGp1c3QgZm9yIGNoYXJhY3RlcnMgaW4gdGhlIG1pZGRsZSBvZiB0aGUgc3Vic3RyaW5nIAoJICAgICAgICAgICAgLy8gZm9yIG1hdGNoaW5nIHRoYXQgZmFpbGVkLgoJICAgICAgICAgICAgaW50IGFkanVzdCA9IHBhdHRlcm5jZWluZGV4OwoJICAgICAgICAgICAgaWYgKGFkanVzdCA+IDEgJiYgc2hpZnQgPiBhZGp1c3QpIHsKCSAgICAgICAgICAgICAgICBzaGlmdCAtPSBhZGp1c3QgLSAxOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgdGV4dG9mZnNldCAtPSBzaGlmdDsKCSAgICAgICAgfQoJICAgICAgICBlbHNlIHsKCSAgICAgICAgICAgIHRleHRvZmZzZXQgLT0gbV9wYXR0ZXJuXy5tX2RlZmF1bHRTaGlmdFNpemVfOwoJICAgICAgICB9CgkgICAgfSAgICAKICAgICAgICAKCSAgICB0ZXh0b2Zmc2V0ID0gZ2V0UHJldmlvdXNCYXNlT2Zmc2V0KHRleHRvZmZzZXQpOwoJICAgIHJldHVybiB0ZXh0b2Zmc2V0OwoJfQoKCS8qKgoJICogQ2hlY2tzIG1hdGNoIGZvciBjb250cmFjdGlvbi4gCgkgKiBJZiB0aGUgbWF0Y2ggc3RhcnRzIHdpdGggYSBwYXJ0aWFsIGNvbnRyYWN0aW9uIHdlIGZhaWwuCgkgKiBVc2VzIHRoZSB0ZW1wb3JhcnkgdXRpbGl0eSBidWZmZXIgdG8gcmV0dXJuIHRoZSBtb2RpZmllZCBzdGFydCBhbmQgZW5kLgoJICogQHBhcmFtIHN0YXJ0IG9mZnNldCBvZiBwb3RlbnRpYWwgbWF0Y2gsIHRvIGJlIG1vZGlmaWVkIGlmIG5lY2Vzc2FyeQoJICogQHBhcmFtIGVuZCBvZmZzZXQgb2YgcG90ZW50aWFsIG1hdGNoLCB0byBiZSBtb2RpZmllZCBpZiBuZWNlc3NhcnkKCSAqIEByZXR1cm4gdHJ1ZSBpZiBtYXRjaCBwYXNzZXMgdGhlIGNvbnRyYWN0aW9uIHRlc3QsIGZhbHNlIG90aGVyd2lzZS4KCSAqLwoJcHJpdmF0ZSBib29sZWFuIGNoZWNrUHJldmlvdXNFeGFjdENvbnRyYWN0aW9uTWF0Y2goaW50IHN0YXJ0LCBpbnQgZW5kKSAKCXsKCSAgICAvLyBUaGlzIHBhcnQgY2hlY2tzIGlmIGVpdGhlciBlbmRzIG9mIHRoZSBtYXRjaCBjb250YWlucyBwb3RlbnRpYWwgCgkgICAgLy8gY29udHJhY3Rpb24uIElmIHNvIHdlJ2xsIGhhdmUgdG8gaXRlcmF0ZSB0aHJvdWdoIHRoZW0KCSAgICBjaGFyIGVjaGFyID0gMDsKCSAgICBpZiAoZW5kIDwgbV90ZXh0TGltaXRPZmZzZXRfKSB7CgkgICAgCXRhcmdldFRleHQuc2V0SW5kZXgoZW5kKTsKCSAgICAJZWNoYXIgPSB0YXJnZXRUZXh0LmN1cnJlbnQoKTsKCSAgICB9CgkgICAgY2hhciBzY2hhciA9IDA7CgkgICAgaWYgKHN0YXJ0ICsgMSA8IG1fdGV4dExpbWl0T2Zmc2V0XykgewoJICAgIAl0YXJnZXRUZXh0LnNldEluZGV4KHN0YXJ0ICsgMSk7CgkgICAgCXNjaGFyID0gdGFyZ2V0VGV4dC5jdXJyZW50KCk7CgkgICAgfQoJICAgIGlmIChtX2NvbGxhdG9yXy5pc1Vuc2FmZShlY2hhcikgfHwgbV9jb2xsYXRvcl8uaXNVbnNhZmUoc2NoYXIpKSB7CgkgICAgCS8vIGV4cGFuc2lvbiBzdWZmaXgsIHdoYXQncyBsZWZ0IHRvIGl0ZXJhdGUKCSAgICAgICAgaW50IGV4cGFuc2lvbiA9IG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJTaXplXyAKCSAgICAgICAgCQkJCQkJCQktIG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJPZmZzZXRfOwoJICAgICAgICBib29sZWFuIGhhc0V4cGFuc2lvbiA9IGV4cGFuc2lvbiA+IDA7CgkgICAgICAgIG1fY29sRUl0ZXJfLnNldEV4YWN0T2Zmc2V0KGVuZCk7CgkgICAgICAgIGludCB0ZW1wID0gZW5kOwoJICAgICAgICB3aGlsZSAoZXhwYW5zaW9uID4gMCkgewoJICAgICAgICAgICAgLy8gZ2V0dGluZyByaWQgb2YgdGhlIHJlZHVuZGFudCBjZQoJICAgICAgICAgICAgLy8gc2luY2UgZm9yd2FyZCBjb250cmFjdGlvbi9leHBhbnNpb24gbWF5IGhhdmUgZXh0cmEgY2VzCgkgICAgICAgICAgICAvLyBpZiB3ZSBhcmUgaW4gdGhlIG5vcm1hbGl6YXRpb24gYnVmZmVyLCBoYXNBY2NlbnRzQmVmb3JlTWF0Y2gKCSAgICAgICAgICAgIC8vIHdvdWxkIGhhdmUgdGFrZW4gY2FyZSBvZiBpdC4KCSAgICAgICAgICAgIC8vIEUuZy4gdGhlIGNoYXJhY3RlciBcdTAxRkEgd2lsbCBoYXZlIGFuIGV4cGFuc2lvbiBvZiAzLCBidXQgaWYKCSAgICAgICAgICAgIC8vIHdlIGFyZSBvbmx5IGxvb2tpbmcgZm9yIEEgcmluZyBBXHUwMzBBLCB3ZSdsbCBoYXZlIHRvIHNraXAgdGhlIAoJICAgICAgICAgICAgLy8gbGFzdCBjZSBpbiB0aGUgZXhwYW5zaW9uIGJ1ZmZlcgoJICAgICAgICAgICAgbV9jb2xFSXRlcl8ucHJldmlvdXMoKTsKCSAgICAgICAgICAgIGlmIChtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKSAhPSB0ZW1wKSB7CgkgICAgICAgICAgICAgICAgZW5kID0gdGVtcDsKCSAgICAgICAgICAgICAgICB0ZW1wID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBleHBhbnNpb24gLS07CgkgICAgICAgIH0KCQoJICAgICAgICBpbnQgY291bnQgPSBtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfOwoJICAgICAgICB3aGlsZSAoY291bnQgPiAwKSB7CgkgICAgICAgICAgICBpbnQgY2UgPSBnZXRDRShtX2NvbEVJdGVyXy5wcmV2aW91cygpKTsKCSAgICAgICAgICAgIC8vIHN0YXR1cyBjaGVja2VkIGJlbG93LCBub3RlIHRoYXQgaWYgc3RhdHVzIGlzIGEgZmFpbHVyZQoJICAgICAgICAgICAgLy8gdWNvbF9wcmV2aW91cyByZXR1cm5zIFVDT0xfTlVMTE9SREVSCgkgICAgICAgICAgICBpZiAoY2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKGhhc0V4cGFuc2lvbiAmJiBjb3VudCA9PSAwIAoJICAgICAgICAgICAgCSYmIG1fY29sRUl0ZXJfLmdldE9mZnNldCgpICE9IHRlbXApIHsKCSAgICAgICAgICAgICAgICBlbmQgPSB0ZW1wOwoJICAgICAgICAgICAgICAgIHRlbXAgPSBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGlmIChjZSAhPSBtX3BhdHRlcm5fLm1fQ0VfW2NvdW50IC0gMV0pIHsKCSAgICAgICAgICAgICAgICBzdGFydCAtLTsKCSAgICAgICAgICAgICAgICBzdGFydCA9IGdldFByZXZpb3VzQmFzZU9mZnNldCh0YXJnZXRUZXh0LCBzdGFydCk7CgkgICAgICAgICAgICAgICAgbV91dGlsQnVmZmVyX1swXSA9IHN0YXJ0OwoJICAgICAgICAgICAgICAgIG1fdXRpbEJ1ZmZlcl9bMV0gPSBlbmQ7CgkgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgY291bnQgLS07CgkgICAgICAgIH0KCSAgICB9IAoJICAgIG1fdXRpbEJ1ZmZlcl9bMF0gPSBzdGFydDsKCSAgICBtX3V0aWxCdWZmZXJfWzFdID0gZW5kOwoJICAgIHJldHVybiB0cnVlOwoJfQoJCgkvKioKCSAqIENoZWNrcyBhbmQgc2V0cyB0aGUgbWF0Y2ggaW5mb3JtYXRpb24gaWYgZm91bmQuCgkgKiBDaGVja3MgCgkgKiA8dWw+CgkgKiA8bGk+IHRoZSBjdXJyZW50IG1hdGNoIGRvZXMgbm90IHJlcGVhdCB0aGUgbGFzdCBtYXRjaAoJICogPGxpPiBib3VuZGFyaWVzIGFyZSBjb3JyZWN0CgkgKiA8bGk+IGV4YWN0IG1hdGNoZXMgaGFzIG5vIGV4dHJhIGFjY2VudHMKCSAqIDxsaT4gaWRlbnRpY2FsIG1hdGNoZXMKCSAqIDwvdWw+CgkgKiBPdGhlcndpc2UgdGhlIG9mZnNldCB3aWxsIGJlIHNoaWZ0ZWQgdG8gdGhlIHByZWNlZGluZyBjaGFyYWN0ZXIuCgkgKiBVc2VzIHRoZSB0ZW1wb3JhcnkgdXRpbGl0eSBidWZmZXIgdG8gc3RvcmUgdGhlIG1vZGlmaWVkIHRleHRvZmZzZXQuCgkgKiBAcGFyYW0gdGV4dG9mZnNldCBvZmZzZXQgaW4gdGhlIGNvbGxhdGlvbiBlbGVtZW50IHRleHQuIHRoZSByZXR1cm5lZCB2YWx1ZQoJICogICAgICAgIHdpbGwgYmUgdGhlIHRydW5jYXRlZCBzdGFydCBvZmZzZXQgb2YgdGhlIG1hdGNoIG9yIHRoZSBuZXcgc3RhcnQgCgkgKiAgICAgICAgc2VhcmNoIG9mZnNldC4KCSAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbWF0Y2ggaXMgdmFsaWQsIGZhbHNlIG90aGVyd2lzZQoJICovCglwcml2YXRlIGZpbmFsIGJvb2xlYW4gY2hlY2tQcmV2aW91c0V4YWN0TWF0Y2goaW50IHRleHRvZmZzZXQpCgl7CgkgICAgLy8gdG8gZW5zdXJlIHRoYXQgdGhlIHN0YXJ0IGFuZCBlbmRzIGFyZSBub3QgY29tcG9zaXRlIGNoYXJhY3RlcnMKCSAgICBpbnQgZW5kID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7ICAgICAgICAKCSAgICBpZiAoIWNoZWNrUHJldmlvdXNFeGFjdENvbnRyYWN0aW9uTWF0Y2godGV4dG9mZnNldCwgZW5kKSkgewoJICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgfQoJICAgIHRleHRvZmZzZXQgPSBtX3V0aWxCdWZmZXJfWzBdOwoJICAgIGVuZCA9IG1fdXRpbEJ1ZmZlcl9bMV07CgkgICAgICAgIAoJICAgIC8vIHRoaXMgdG90YWxseSBtYXRjaGVzLCBob3dldmVyIHdlIG5lZWQgdG8gY2hlY2sgaWYgaXQgaXMgcmVwZWF0aW5nCgkgICAgLy8gdGhlIG9sZCBtYXRjaAoJICAgIGlmIChjaGVja1JlcGVhdGVkTWF0Y2godGV4dG9mZnNldCwgZW5kKSAKCSAgICAJfHwgIWlzQnJlYWtVbml0KHRleHRvZmZzZXQsIGVuZCkgCgkgICAgCXx8IGhhc0FjY2VudHNCZWZvcmVNYXRjaCh0ZXh0b2Zmc2V0LCBlbmQpIAoJICAgIAl8fCAhY2hlY2tJZGVudGljYWwodGV4dG9mZnNldCwgZW5kKSAKCSAgICAJfHwgaGFzQWNjZW50c0FmdGVyTWF0Y2godGV4dG9mZnNldCwgZW5kKSkgewoJICAgICAgICB0ZXh0b2Zmc2V0IC0tOwoJICAgICAgICB0ZXh0b2Zmc2V0ID0gZ2V0UHJldmlvdXNCYXNlT2Zmc2V0KHRhcmdldFRleHQsIHRleHRvZmZzZXQpOwoJICAgICAgICBtX3V0aWxCdWZmZXJfWzBdID0gdGV4dG9mZnNldDsKCSAgICAgICAgcmV0dXJuIGZhbHNlOwoJICAgIH0KCSAgICBtX21hdGNoZWRJbmRleF8gPSB0ZXh0b2Zmc2V0OwoJICAgIG1hdGNoTGVuZ3RoID0gZW5kIC0gdGV4dG9mZnNldDsKCSAgICByZXR1cm4gdHJ1ZTsKCX0KCgkvKioKCSAqIFJlYXJyYW5nZXMgdGhlIGVuZCBhY2NlbnRzIHRvIHRyeSBtYXRjaGluZy4KCSAqIFN1ZmZpeCBhY2NlbnRzIGluIHRoZSB0ZXh0IHdpbGwgYmUgZ3JvdXBlZCBhY2NvcmRpbmcgdG8gdGhlaXIgY29tYmluaW5nIAoJICogY2xhc3MgYW5kIHRoZSBncm91cHMgd2lsbCBiZSBtaXhlZCBhbmQgbWF0Y2hlZCB0byB0cnkgZmluZCB0aGUgcGVyZmVjdCAKCSAqIG1hdGNoIHdpdGggdGhlIHBhdHRlcm4uCgkgKiBTbyBmb3IgaW5zdGFuY2UgbG9va2luZyBmb3IgIlx1MDMwMSIgaW4gIlx1MDMwQVx1MDMwMVx1MDMyNSIKCSAqIHN0ZXAgMTogc3BsaXQgIlx1MDMwQVx1MDMwMSIgaW50byA2IG90aGVyIHR5cGUgb2YgcG90ZW50aWFsIGFjY2VudCAKCSAqIAkJCXN1YnN0cmluZ3MKCSAqICAgICAgICAgIlx1MDMwQSIsICJcdTAzMDEiLCAiXHUwMzI1IiwgIlx1MDMwQVx1MDMwMSIsICJcdTAzMEFcdTAzMjUiLCAKCSAqICAgICAgICAgIlx1MDMwMVx1MDMyNSIuCgkgKiBzdGVwIDI6IGNoZWNrIGlmIGFueSBvZiB0aGUgZ2VuZXJhdGVkIHN1YnN0cmluZ3MgbWF0Y2hlcyB0aGUgcGF0dGVybi4KCSAqIEBwYXJhbSBzdGFydCBvZmZzZXQgb2YgdGhlIGZpcnN0IGJhc2UgY2hhcmFjdGVyCgkgKiBAcGFyYW0gZW5kIHN0YXJ0IG9mIHRoZSBsYXN0IGFjY2VudCBzZXQKCSAqIEByZXR1cm4gRE9ORSBpZiBhIG1hdGNoIGlzIG5vdCBmb3VuZCwgb3RoZXJ3aXNlIHJldHVybiB0aGUgZW5kaW5nCgkgKiAgICAgICAgIG9mZnNldCBvZiB0aGUgbWF0Y2guIE5vdGUgdGhpcyBzdGFydCBpbmNsdWRlcyBhbGwgZm9sbG93aW5nIAoJICogICAgICAgICBhY2NlbnRzLgoJICovCglwcml2YXRlIGludCBkb1ByZXZpb3VzQ2Fub25pY2FsU3VmZml4TWF0Y2goaW50IHN0YXJ0LCBpbnQgZW5kKQoJewoJICAgIHRhcmdldFRleHQuc2V0SW5kZXgoZW5kKTsKCQlpZiAoVVRGMTYuaXNUcmFpbFN1cnJvZ2F0ZSh0YXJnZXRUZXh0LnByZXZpb3VzKCkpIAoJCQkmJiB0YXJnZXRUZXh0LmdldEluZGV4KCkgPiBtX3RleHRCZWdpbk9mZnNldF8pIHsKCQkJaWYgKCFVVEYxNi5pc0xlYWRTdXJyb2dhdGUodGFyZ2V0VGV4dC5wcmV2aW91cygpKSkgewoJCQkJdGFyZ2V0VGV4dC5uZXh0KCk7CgkJCX0gCgkJfQoJICAgIGlmICgoZ2V0RkNEKHRhcmdldFRleHQsIHRhcmdldFRleHQuZ2V0SW5kZXgoKSkgJiBMQVNUX0JZVEVfTUFTS18pID09IDApIHsKCSAgICAgICAgLy8gZGllLi4uIGZhaWxlZCBhdCBhIGJhc2UgY2hhcmFjdGVyCgkgICAgICAgIHJldHVybiBET05FOwoJICAgIH0KCSAgICBlbmQgPSBnZXROZXh0QmFzZU9mZnNldCh0YXJnZXRUZXh0LCBlbmQpOwoJCgkgICAgU3RyaW5nQnVmZmVyIGFjY2VudHMgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CgkgICAgaW50IG9mZnNldCA9IGdldFByZXZpb3VzQmFzZU9mZnNldCh0YXJnZXRUZXh0LCBlbmQpOwoJICAgIC8vIG5vcm1hbGl6aW5nIHRoZSBvZmZlbnNpdmUgc3RyaW5nCgkgICAgU3RyaW5nIGFjY2VudHN0ciA9IGdldFN0cmluZyh0YXJnZXRUZXh0LCBvZmZzZXQsIGVuZCAtIG9mZnNldCk7CgkgICAgaWYgKE5vcm1hbGl6ZXIucXVpY2tDaGVjayhhY2NlbnRzdHIsIE5vcm1hbGl6ZXIuTkZEKSAKCSAgICAgICAgCQkJCQkJCQkJCT09IE5vcm1hbGl6ZXIuTk8pIHsKCSAgICAgICAgYWNjZW50c3RyID0gTm9ybWFsaXplci5kZWNvbXBvc2UoYWNjZW50c3RyLCBmYWxzZSk7CgkgICAgfQoJICAgIGFjY2VudHMuYXBwZW5kKGFjY2VudHN0cik7ICAgIAoJICAgICAgICAKCSAgICBpbnQgYWNjZW50c2luZGV4W10gPSBuZXcgaW50W0lOSVRJQUxfQVJSQVlfU0laRV9dOyAgICAgIAoJICAgIGludCBhY2NlbnRzaXplID0gZ2V0VW5ibG9ja2VkQWNjZW50SW5kZXgoYWNjZW50cywgYWNjZW50c2luZGV4KTsKCSAgICBpbnQgY291bnQgPSAoMiA8PCAoYWNjZW50c2l6ZSAtIDEpKSAtIDI7ICAKCSAgICB3aGlsZSAoY291bnQgPiAwKSB7CiAgICAgICAgICAgIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18uZGVsZXRlKDAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5sZW5ndGgoKSk7CgkgICAgICAgIC8vIGNvcHkgdGhlIGJhc2UgY2hhcmFjdGVycwoJICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IGFjY2VudHNpbmRleFswXTsgayArKykgewoJICAgICAgICAgICAgIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18uYXBwZW5kKGFjY2VudHMuY2hhckF0KGspKTsKCSAgICAgICAgfQoJICAgICAgICAvLyBmb3JtaW5nIGFsbCBwb3NzaWJsZSBjYW5vbmljYWwgcmVhcnJhbmdlbWVudCBieSBkcm9wcGluZwoJICAgICAgICAvLyBzZXRzIG9mIGFjY2VudHMKCSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gYWNjZW50c2l6ZSAtIDE7IGkgKyspIHsKCSAgICAgICAgICAgIGludCBtYXNrID0gMSA8PCAoYWNjZW50c2l6ZSAtIGkgLSAxKTsKCSAgICAgICAgICAgIGlmICgoY291bnQgJiBtYXNrKSAhPSAwKSB7CgkgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IGFjY2VudHNpbmRleFtpXTsgaiA8IGFjY2VudHNpbmRleFtpICsgMV07IAoJICAgICAgICAgICAgICAgIAkJCQkJCQkJCQkJCQlqICsrKSB7CgkgICAgICAgICAgICAgICAgICAgIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18uYXBwZW5kKGFjY2VudHMuY2hhckF0KGopKTsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICAgICAgU3RyaW5nQnVmZmVyIG1hdGNoID0gbWVyZ2UobV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXywgdGFyZ2V0VGV4dCwKCSAgICAgICAgCQkJCQkJCXN0YXJ0LCBvZmZzZXQsIAoJICAgICAgICAJCQkJCQkJbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXyk7CgkgICAgICAgIC8vIHJ1biB0aGUgY29sbGF0b3IgaXRlcmF0b3IgdGhyb3VnaCB0aGlzIG1hdGNoCgkgICAgICAgIC8vIGlmIHN0YXR1cyBpcyBhIGZhaWx1cmUgdWNvbF9zZXRUZXh0IGRvZXMgbm90aGluZwoJICAgICAgICBtX3V0aWxDb2xFSXRlcl8uc2V0VGV4dChtYXRjaC50b1N0cmluZygpKTsKCSAgICAgICAgaWYgKGNoZWNrQ29sbGF0aW9uTWF0Y2gobV91dGlsQ29sRUl0ZXJfKSkgewoJICAgICAgICAgICAgcmV0dXJuIGVuZDsKCSAgICAgICAgfQoJICAgICAgICBjb3VudCAtLTsKCSAgICB9CgkgICAgcmV0dXJuIERPTkU7Cgl9CgkKCS8qKgoJICogVGFrZSB0aGUgcmVhcnJhbmdlZCBzdGFydCBhY2NlbnRzIGFuZCB0cmllcyBtYXRjaGluZy4gSWYgbWF0Y2ggZmFpbGVkIGF0CgkgKiBhIHNlcGVyYXRlIGZvbGxvd2luZyBzZXQgb2YgYWNjZW50cyAoc2VwZXJhdGVkIGZyb20gdGhlIHJlYXJyYW5nZWQgb24gYnkKCSAqIGF0IGxlYXN0IGEgYmFzZSBjaGFyYWN0ZXIpIHRoZW4gd2UgcmVhcnJhbmdlIHRoZSBwcmVjZWRpbmcgYWNjZW50cyBhbmQgCgkgKiB0cmllcyBtYXRjaGluZyBhZ2Fpbi4KCSAqIFdlIGFsbG93IHNraXBwaW5nIG9mIHRoZSBlbmRzIG9mIHRoZSBhY2NlbnQgc2V0IGlmIHRoZSBjZXMgZG8gbm90IG1hdGNoLiAKCSAqIEhvd2V2ZXIgaWYgdGhlIGZhaWx1cmUgaXMgZm91bmQgYmVmb3JlIHRoZSBhY2NlbnQgc2V0LCBpdCBmYWlscy4KCSAqIEludGVybmFsIG1ldGhvZCwgc3RhdHVzIGFzc3VtZWQgdG8gYmUgc3VjY2VzcywgY2FsbGVyIGhhcyB0byBjaGVjayAKCSAqIHN0YXR1cyBiZWZvcmUgY2FsbGluZyB0aGlzIG1ldGhvZC4KCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IG9mIHRoZSBlbmRzIG9mIHRoZSByZWFycmFuZ2VkIGFjY2VudAoJICogQHJldHVybiBET05FIGlmIGEgbWF0Y2ggaXMgbm90IGZvdW5kLCBvdGhlcndpc2UgcmV0dXJuIHRoZSBlbmRpbmcgb2Zmc2V0IAoJICogCQkJb2YgdGhlIG1hdGNoLiBOb3RlIHRoaXMgc3RhcnQgaW5jbHVkZXMgYWxsIGZvbGxvd2luZyBhY2NlbnRzLgoJICovCglwcml2YXRlIGludCBkb1ByZXZpb3VzQ2Fub25pY2FsUHJlZml4TWF0Y2goaW50IHRleHRvZmZzZXQpCgl7CgkgICAgaW50IHNhZmVsZW5ndGggPSAwOwoJICAgIFN0cmluZ0J1ZmZlciBzYWZldGV4dDsKCSAgICBpbnQgc2FmZW9mZnNldCA9IHRleHRvZmZzZXQ7CgkKCSAgICBpZiAodGV4dG9mZnNldCA+IG1fdGV4dEJlZ2luT2Zmc2V0XwoJICAgIAkmJiBtX2NvbGxhdG9yXy5pc1Vuc2FmZShtX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfLmNoYXJBdCgKCSAgICAJCQkJCQkJbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5sZW5ndGgoKSAtIDEpKSkgewoJICAgICAgICBzYWZlb2Zmc2V0ID0gZ2V0TmV4dFNhZmVPZmZzZXQodGV4dG9mZnNldCwgbV90ZXh0TGltaXRPZmZzZXRfKTsKCSAgICAgICAgc2FmZWxlbmd0aCA9IHNhZmVvZmZzZXQgLSB0ZXh0b2Zmc2V0OwoJICAgICAgICBzYWZldGV4dCA9IG1lcmdlKG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18sIHRhcmdldFRleHQsIHRleHRvZmZzZXQsIAoJICAgICAgICAJCQkJIHNhZmVvZmZzZXQsIG51bGwpOwoJICAgIH0KCSAgICBlbHNlIHsKCSAgICAgICAgc2FmZXRleHQgPSBtX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfOwoJICAgIH0KCQoJICAgIC8vIGlmIHN0YXR1cyBpcyBhIGZhaWx1cmUsIHVjb2xfc2V0VGV4dCBkb2VzIG5vdGhpbmcKCSAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgY29sZWl0ZXIgPSBtX3V0aWxDb2xFSXRlcl87CgkgICAgY29sZWl0ZXIuc2V0VGV4dChzYWZldGV4dC50b1N0cmluZygpKTsKCSAgICAvLyBzdGF0dXMgY2hlY2tlZCBpbiBsb29wIGJlbG93CgkgICAgCgkgICAgaW50IGNlaW5kZXggPSAwOwoJICAgIGJvb2xlYW4gaXNTYWZlID0gdHJ1ZTsgLy8gc2FmZSB6b25lIGluZGljYXRpb24gZmxhZyBmb3IgcG9zaXRpb24KCSAgICBpbnQgcHJlZml4bGVuZ3RoID0gbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5sZW5ndGgoKTsKCSAgICAKCSAgICB3aGlsZSAoY2VpbmRleCA8IG1fcGF0dGVybl8ubV9DRUxlbmd0aF8pIHsKCSAgICAgICAgaW50IHRleHRjZSA9IGNvbGVpdGVyLm5leHQoKTsKCSAgICAgICAgaWYgKHRleHRjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CgkgICAgICAgICAgICAvLyBjaGVjayBpZiB3ZSBoYXZlIHBhc3NlZCB0aGUgc2FmZSBidWZmZXIKCSAgICAgICAgICAgIGlmIChjb2xlaXRlciA9PSBtX2NvbEVJdGVyXykgewoJICAgICAgICAgICAgICAgIHJldHVybiBET05FOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKHNhZmV0ZXh0ICE9IG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18pIHsKCSAgICAgICAgICAgIAlzYWZldGV4dC5kZWxldGUoMCwgc2FmZXRleHQubGVuZ3RoKCkpOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgY29sZWl0ZXIgPSBtX2NvbEVJdGVyXzsKCSAgICAgICAgICAgIGNvbGVpdGVyLnNldEV4YWN0T2Zmc2V0KHNhZmVvZmZzZXQpOwoJICAgICAgICAgICAgLy8gc3RhdHVzIGNoZWNrZWQgYXQgdGhlIHN0YXJ0IG9mIHRoZSBsb29wCgkgICAgICAgICAgICBpc1NhZmUgPSBmYWxzZTsKCSAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICB9CgkgICAgICAgIHRleHRjZSA9IGdldENFKHRleHRjZSk7CgkgICAgICAgIGlmICh0ZXh0Y2UgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSAKCSAgICAgICAgCSYmIHRleHRjZSAhPSBtX3BhdHRlcm5fLm1fQ0VfW2NlaW5kZXhdKSB7CgkgICAgICAgICAgICAvLyBkbyB0aGUgYmVnaW5uaW5nIHN0dWZmCgkgICAgICAgICAgICBpbnQgZmFpbGVkb2Zmc2V0ID0gY29sZWl0ZXIuZ2V0T2Zmc2V0KCk7CgkgICAgICAgICAgICBpZiAoaXNTYWZlICYmIGZhaWxlZG9mZnNldCA8PSBwcmVmaXhsZW5ndGgpIHsKCSAgICAgICAgICAgICAgICAvLyBhbGFzLi4uIG5vIGhvcGUuIGZhaWxlZCBhdCByZWFycmFuZ2VkIGFjY2VudCBzZXQKCSAgICAgICAgICAgICAgICByZXR1cm4gRE9ORTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGVsc2UgewoJICAgICAgICAgICAgICAgIGlmIChpc1NhZmUpIHsKCSAgICAgICAgICAgICAgICAgICAgZmFpbGVkb2Zmc2V0ID0gc2FmZW9mZnNldCAtIGZhaWxlZG9mZnNldDsKCSAgICAgICAgICAgICAgICAgICAgaWYgKHNhZmV0ZXh0ICE9IG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18pIHsKCSAgICAgICAgICAgIAkJCXNhZmV0ZXh0LmRlbGV0ZSgwLCBzYWZldGV4dC5sZW5ndGgoKSk7CgkgICAgICAgICAgICAJCX0KCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgCgkgICAgICAgICAgICAgICAgLy8gdHJ5IHJlYXJyYW5naW5nIHRoZSBlbmQgYWNjZW50cwoJICAgICAgICAgICAgICAgIGludCByZXN1bHQgPSBkb1ByZXZpb3VzQ2Fub25pY2FsU3VmZml4TWF0Y2godGV4dG9mZnNldCwgCgkgICAgICAgICAgICAgICAgCQkJCQkJCQkJCQlmYWlsZWRvZmZzZXQpOwoJICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gRE9ORSkgewoJICAgICAgICAgICAgICAgICAgICAvLyBpZiBzdGF0dXMgaXMgYSBmYWlsdXJlLCB1Y29sX3NldE9mZnNldCBkb2VzIG5vdGhpbmcKCSAgICAgICAgICAgICAgICAgICAgbV9jb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQocmVzdWx0KTsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgICAgICBpZiAodGV4dGNlID09IG1fcGF0dGVybl8ubV9DRV9bY2VpbmRleF0pIHsKCSAgICAgICAgICAgIGNlaW5kZXggKys7CgkgICAgICAgIH0KCSAgICB9CgkgICAgLy8gc2V0IG9mZnNldCBoZXJlCgkgICAgaWYgKGlzU2FmZSkgewoJICAgICAgICBpbnQgcmVzdWx0ID0gY29sZWl0ZXIuZ2V0T2Zmc2V0KCk7CgkgICAgICAgIC8vIHNldHMgdGhlIHRleHQgaXRlcmF0b3IgaGVyZSB3aXRoIHRoZSBjb3JyZWN0IGV4cGFuc2lvbiBhbmQgb2Zmc2V0CgkgICAgICAgIGludCBsZWZ0b3ZlcmNlcyA9IGNvbGVpdGVyLm1fQ0VCdWZmZXJTaXplXyAKCSAgICAgICAgCQkJCQkJCQkJLSBjb2xlaXRlci5tX0NFQnVmZmVyT2Zmc2V0XzsKCSAgICAgICAgaWYgKHJlc3VsdCA8PSBwcmVmaXhsZW5ndGgpIHsgCgkgICAgICAgICAgICByZXN1bHQgPSB0ZXh0b2Zmc2V0OwoJICAgICAgICB9CgkgICAgICAgIGVsc2UgewoJICAgICAgICAgICAgcmVzdWx0ID0gdGV4dG9mZnNldCArIChzYWZlb2Zmc2V0IC0gcmVzdWx0KTsKCSAgICAgICAgfQoJICAgICAgICBtX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldChyZXN1bHQpOwoJICAgICAgICBtX2NvbEVJdGVyXy5tX0NFQnVmZmVyT2Zmc2V0XyA9IG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJTaXplXyAKCSAgICAgICAgCQkJCQkJCQkJCQkJCS0gbGVmdG92ZXJjZXM7CgkgICAgICAgIHJldHVybiByZXN1bHQ7CgkgICAgfQoJICAgIAoJICAgIHJldHVybiBjb2xlaXRlci5nZXRPZmZzZXQoKTsgICAgICAgICAgICAgIAoJfQoJCgkvKioKCSAqIFRyeWluZyBvdXQgdGhlIHN1YnN0cmluZyBhbmQgc2VlcyBpZiBpdCBjYW4gYmUgYSBjYW5vbmljYWwgbWF0Y2guCgkgKiBUaGlzIHdpbGwgdHJ5IG5vcm1hbGl6aW5nIHRoZSBzdGFydGluZyBhY2NlbnRzIGFuZCBhcnJhbmdpbmcgdGhlbSBpbnRvIAoJICogY2Fub25pY2FsIGVxdWl2YWxlbnRzIGFuZCBjaGVjayB0aGVpciBjb3JyZXNwb25kaW5nIGNlcyB3aXRoIHRoZSBwYXR0ZXJuIAoJICogY2UuCgkgKiBQcmVmaXggYWNjZW50cyBpbiB0aGUgdGV4dCB3aWxsIGJlIGdyb3VwZWQgYWNjb3JkaW5nIHRvIHRoZWlyIGNvbWJpbmluZyAKCSAqIGNsYXNzIGFuZCB0aGUgZ3JvdXBzIHdpbGwgYmUgbWl4ZWQgYW5kIG1hdGNoZWQgdG8gdHJ5IGZpbmQgdGhlIHBlcmZlY3QgCgkgKiBtYXRjaCB3aXRoIHRoZSBwYXR0ZXJuLgoJICogU28gZm9yIGluc3RhbmNlIGxvb2tpbmcgZm9yICJcdTAzMDEiIGluICJcdTAzMEFcdTAzMDFcdTAzMjUiCgkgKiBzdGVwIDE6IHNwbGl0ICJcdTAzMEFcdTAzMDEiIGludG8gNiBvdGhlciB0eXBlIG9mIHBvdGVudGlhbCBhY2NlbnQgCgkgKiAJCSAgIHN1YnN0cmluZ3MKCSAqICAgICAgICAgIlx1MDMwQSIsICJcdTAzMDEiLCAiXHUwMzI1IiwgIlx1MDMwQVx1MDMwMSIsICJcdTAzMEFcdTAzMjUiLCAKCSAqICAgICAgICAgIlx1MDMwMVx1MDMyNSIuCgkgKiBzdGVwIDI6IGNoZWNrIGlmIGFueSBvZiB0aGUgZ2VuZXJhdGVkIHN1YnN0cmluZ3MgbWF0Y2hlcyB0aGUgcGF0dGVybi4KCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IHN0YXJ0IG9mZnNldCBpbiB0aGUgY29sbGF0aW9uIGVsZW1lbnQgdGV4dCB0aGF0IHN0YXJ0cyAKCSAqICAgICAgICAgICAgICAgICAgIHdpdGggdGhlIGFjY2VudHMgdG8gYmUgcmVhcnJhbmdlZAoJICogQHJldHVybiB0cnVlIGlmIHRoZSBtYXRjaCBpcyB2YWxpZCwgZmFsc2Ugb3RoZXJ3aXNlCgkgKi8KCXByaXZhdGUgYm9vbGVhbiBkb1ByZXZpb3VzQ2Fub25pY2FsTWF0Y2goaW50IHRleHRvZmZzZXQpCgl7CiAgICAgICAgaW50IG9mZnNldCA9IG1fY29sRUl0ZXJfLmdldE9mZnNldCgpOwoJICAgIGlmICgoZ2V0RkNEKHRhcmdldFRleHQsIHRleHRvZmZzZXQpID4+IFNFQ09ORF9MQVNUX0JZVEVfU0hJRlRfKSA9PSAwKSB7CgkgICAgICAgIGlmIChtX3BhdHRlcm5fLm1faGFzU3VmZml4QWNjZW50c18pIHsKCSAgICAgICAgICAgIG9mZnNldCA9IGRvUHJldmlvdXNDYW5vbmljYWxTdWZmaXhNYXRjaCh0ZXh0b2Zmc2V0LCBvZmZzZXQpOwoJICAgICAgICAgICAgaWYgKG9mZnNldCAhPSBET05FKSB7CgkgICAgICAgICAgICAgICAgbV9jb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQob2Zmc2V0KTsKCSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgfQoJCgkgICAgaWYgKCFtX3BhdHRlcm5fLm1faGFzUHJlZml4QWNjZW50c18pIHsKCSAgICAgICAgcmV0dXJuIGZhbHNlOwoJICAgIH0KCQoJICAgIFN0cmluZ0J1ZmZlciBhY2NlbnRzID0gbmV3IFN0cmluZ0J1ZmZlcigpOwoJICAgIC8vIG9mZnNldCB0byB0aGUgbGFzdCBiYXNlIGNoYXJhY3RlciBpbiBzdWJzdHJpbmcgdG8gc2VhcmNoCgkgICAgaW50IGJhc2VvZmZzZXQgPSBnZXROZXh0QmFzZU9mZnNldCh0YXJnZXRUZXh0LCB0ZXh0b2Zmc2V0KTsKCSAgICAvLyBub3JtYWxpemluZyB0aGUgb2ZmZW5zaXZlIHN0cmluZwoJICAgIFN0cmluZyB0ZXh0c3RyID0gZ2V0U3RyaW5nKHRhcmdldFRleHQsIHRleHRvZmZzZXQsIAoJICAgIAkJCQkJCQkJCQkJYmFzZW9mZnNldCAtIHRleHRvZmZzZXQpOwoJICAgIGlmIChOb3JtYWxpemVyLnF1aWNrQ2hlY2sodGV4dHN0ciwgTm9ybWFsaXplci5ORkQpIAoJICAgICAgICAJCQkJCQkJCQkJPT0gTm9ybWFsaXplci5OTykgewoJICAgICAgICB0ZXh0c3RyID0gTm9ybWFsaXplci5kZWNvbXBvc2UodGV4dHN0ciwgZmFsc2UpOwoJICAgIH0KCSAgICBhY2NlbnRzLmFwcGVuZCh0ZXh0c3RyKTsKCSAgICAvLyBzdGF0dXMgY2hlY2tlZCBpbiBsb29wCgkgICAgICAgIAoJICAgIGludCBhY2NlbnRzaW5kZXhbXSA9IG5ldyBpbnRbSU5JVElBTF9BUlJBWV9TSVpFX107CgkgICAgaW50IHNpemUgPSBnZXRVbmJsb2NrZWRBY2NlbnRJbmRleChhY2NlbnRzLCBhY2NlbnRzaW5kZXgpOwoJCgkgICAgLy8gMiBwb3dlciBuIC0gMSBtaW51cyB0aGUgZnVsbCBzZXQgb2YgYWNjZW50cwoJICAgIGludCBjb3VudCA9ICgyIDw8IChzaXplIC0gMSkpIC0gMjsgIAoJICAgIHdoaWxlIChjb3VudCA+IDApIHsKCSAgICAJbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5kZWxldGUoMCwgCgkgICAgCQkJCQkJCQltX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfLmxlbmd0aCgpKTsKCSAgICAgICAgLy8gY29weSB0aGUgYmFzZSBjaGFyYWN0ZXJzCgkgICAgICAgIGZvciAoaW50IGsgPSAwOyBrIDwgYWNjZW50c2luZGV4WzBdOyBrICsrKSB7CgkgICAgICAgICAgICBtX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfLmFwcGVuZChhY2NlbnRzLmNoYXJBdChrKSk7CgkgICAgICAgIH0KCSAgICAgICAgLy8gZm9ybWluZyBhbGwgcG9zc2libGUgY2Fub25pY2FsIHJlYXJyYW5nZW1lbnQgYnkgZHJvcHBpbmcKCSAgICAgICAgLy8gc2V0cyBvZiBhY2NlbnRzCgkgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDw9IHNpemUgLSAxOyBpICsrKSB7CgkgICAgICAgICAgICBpbnQgbWFzayA9IDEgPDwgKHNpemUgLSBpIC0gMSk7CgkgICAgICAgICAgICBpZiAoKGNvdW50ICYgbWFzaykgIT0gMCkgewoJICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSBhY2NlbnRzaW5kZXhbaV07IGogPCBhY2NlbnRzaW5kZXhbaSArIDFdOyAKCSAgICAgICAgICAgICAgICAJIGogKyspIHsKCSAgICAgICAgICAgICAgICAgICAgbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5hcHBlbmQoYWNjZW50cy5jaGFyQXQoaikpOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgICAgICBvZmZzZXQgPSBkb1ByZXZpb3VzQ2Fub25pY2FsUHJlZml4TWF0Y2goYmFzZW9mZnNldCk7CgkgICAgICAgIGlmIChvZmZzZXQgIT0gRE9ORSkgewoJICAgICAgICAgICAgcmV0dXJuIHRydWU7IC8vIG1hdGNoIGZvdW5kCgkgICAgICAgIH0KCSAgICAgICAgY291bnQgLS07CgkgICAgfQoJICAgIHJldHVybiBmYWxzZTsKCX0KCQoJLyoqCgkgKiBDaGVja3MgbWF0Y2ggZm9yIGNvbnRyYWN0aW9uLiAKCSAqIElmIHRoZSBtYXRjaCBzdGFydHMgd2l0aCBhIHBhcnRpYWwgY29udHJhY3Rpb24gd2UgZmFpbC4KCSAqIFVzZXMgdGhlIHRlbXBvcmFyeSB1dGlsaXR5IGJ1ZmZlciB0byByZXR1cm4gdGhlIG1vZGlmaWVkIHN0YXJ0IGFuZCBlbmQuCgkgKiBAcGFyYW0gc3RhcnQgb2Zmc2V0IG9mIHBvdGVudGlhbCBtYXRjaCwgdG8gYmUgbW9kaWZpZWQgaWYgbmVjZXNzYXJ5CgkgKiBAcGFyYW0gZW5kIG9mZnNldCBvZiBwb3RlbnRpYWwgbWF0Y2gsIHRvIGJlIG1vZGlmaWVkIGlmIG5lY2Vzc2FyeQoJICogQHJldHVybiB0cnVlIGlmIG1hdGNoIHBhc3NlcyB0aGUgY29udHJhY3Rpb24gdGVzdCwgZmFsc2Ugb3RoZXJ3aXNlLgoJICovCglwcml2YXRlIGJvb2xlYW4gY2hlY2tQcmV2aW91c0Nhbm9uaWNhbENvbnRyYWN0aW9uTWF0Y2goaW50IHN0YXJ0LCBpbnQgZW5kKSAKCXsKCSAgICBpbnQgdGVtcCA9IGVuZDsKCSAgICAvLyBUaGlzIHBhcnQgY2hlY2tzIGlmIGVpdGhlciBlbmRzIG9mIHRoZSBtYXRjaCBjb250YWlucyBwb3RlbnRpYWwgCgkgICAgLy8gY29udHJhY3Rpb24uIElmIHNvIHdlJ2xsIGhhdmUgdG8gaXRlcmF0ZSB0aHJvdWdoIHRoZW0KCSAgICBjaGFyIGVjaGFyID0gMDsKCSAgICBjaGFyIHNjaGFyID0gMDsKCSAgICBpZiAoZW5kIDwgbV90ZXh0TGltaXRPZmZzZXRfKSB7CgkgICAgCXRhcmdldFRleHQuc2V0SW5kZXgoZW5kKTsKCSAgICAJZWNoYXIgPSB0YXJnZXRUZXh0LmN1cnJlbnQoKTsKCSAgICB9CgkgICAgaWYgKHN0YXJ0ICsgMSA8IG1fdGV4dExpbWl0T2Zmc2V0XykgewoJICAgIAl0YXJnZXRUZXh0LnNldEluZGV4KHN0YXJ0ICsgMSk7CgkgICAgCXNjaGFyID0gdGFyZ2V0VGV4dC5jdXJyZW50KCk7CgkgICAgfQoJICAgIGlmIChtX2NvbGxhdG9yXy5pc1Vuc2FmZShlY2hhcikgfHwgbV9jb2xsYXRvcl8uaXNVbnNhZmUoc2NoYXIpKSB7CgkgICAgICAgIGludCBleHBhbnNpb24gPSBtX2NvbEVJdGVyXy5tX0NFQnVmZmVyU2l6ZV8gCgkgICAgICAgIAkJCQkJCQkJLSBtX2NvbEVJdGVyXy5tX0NFQnVmZmVyT2Zmc2V0XzsKCSAgICAgICAgYm9vbGVhbiBoYXNFeHBhbnNpb24gPSBleHBhbnNpb24gPiAwOwoJICAgICAgICBtX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldChlbmQpOwoJICAgICAgICB3aGlsZSAoZXhwYW5zaW9uID4gMCkgewoJICAgICAgICAgICAgLy8gZ2V0dGluZyByaWQgb2YgdGhlIHJlZHVuZGFudCBjZQoJICAgICAgICAgICAgLy8gc2luY2UgZm9yd2FyZCBjb250cmFjdGlvbi9leHBhbnNpb24gbWF5IGhhdmUgZXh0cmEgY2VzCgkgICAgICAgICAgICAvLyBpZiB3ZSBhcmUgaW4gdGhlIG5vcm1hbGl6YXRpb24gYnVmZmVyLCBoYXNBY2NlbnRzQmVmb3JlTWF0Y2gKCSAgICAgICAgICAgIC8vIHdvdWxkIGhhdmUgdGFrZW4gY2FyZSBvZiBpdC4KCSAgICAgICAgICAgIC8vIEUuZy4gdGhlIGNoYXJhY3RlciBcdTAxRkEgd2lsbCBoYXZlIGFuIGV4cGFuc2lvbiBvZiAzLCBidXQgCgkgICAgICAgICAgICAvLyBpZiB3ZSBhcmUgb25seSBsb29raW5nIGZvciBBIHJpbmcgQVx1MDMwQSwgd2UnbGwgaGF2ZSB0byAKCSAgICAgICAgICAgIC8vIHNraXAgdGhlIGxhc3QgY2UgaW4gdGhlIGV4cGFuc2lvbiBidWZmZXIKCSAgICAgICAgICAgIG1fY29sRUl0ZXJfLnByZXZpb3VzKCk7CgkgICAgICAgICAgICBpZiAobV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCkgIT0gdGVtcCkgewoJICAgICAgICAgICAgICAgIGVuZCA9IHRlbXA7CgkgICAgICAgICAgICAgICAgdGVtcCA9IG1fY29sRUl0ZXJfLmdldE9mZnNldCgpOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgZXhwYW5zaW9uIC0tOwoJICAgICAgICB9CgkKCSAgICAgICAgaW50IGNvdW50ID0gbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXzsKCSAgICAgICAgd2hpbGUgKGNvdW50ID4gMCkgewoJICAgICAgICAgICAgaW50IGNlID0gZ2V0Q0UobV9jb2xFSXRlcl8ucHJldmlvdXMoKSk7CgkgICAgICAgICAgICAvLyBzdGF0dXMgY2hlY2tlZCBiZWxvdywgbm90ZSB0aGF0IGlmIHN0YXR1cyBpcyBhIGZhaWx1cmUKCSAgICAgICAgICAgIC8vIHByZXZpb3VzKCkgcmV0dXJucyBOVUxMT1JERVIKCSAgICAgICAgICAgIGlmIChjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CgkgICAgICAgICAgICAgICAgY29udGludWU7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAoaGFzRXhwYW5zaW9uICYmIGNvdW50ID09IDAgCgkgICAgICAgICAgICAJJiYgbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCkgIT0gdGVtcCkgewoJICAgICAgICAgICAgICAgIGVuZCA9IHRlbXA7CgkgICAgICAgICAgICAgICAgdGVtcCA9IG1fY29sRUl0ZXJfLmdldE9mZnNldCgpOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKGNvdW50ID09IG1fcGF0dGVybl8ubV9DRUxlbmd0aF8gCgkgICAgICAgICAgICAJJiYgY2UgIT0gbV9wYXR0ZXJuXy5tX0NFX1ttX3BhdHRlcm5fLm1fQ0VMZW5ndGhfIC0gMV0pIHsKCSAgICAgICAgICAgICAgICAvLyBhY2NlbnRzIG1heSBoYXZlIGV4dHJhIHN0YXJ0aW5nIGNlcywgdGhpcyBvY2N1cnMgd2hlbiBhIAoJICAgICAgICAgICAgICAgIC8vIHB1cmUgYWNjZW50IHBhdHRlcm4gaXMgbWF0Y2hlZCB3aXRob3V0IHJlYXJyYW5nZW1lbnQKCSAgICAgICAgICAgICAgICBpbnQgZXhwZWN0ZWQgPSBtX3BhdHRlcm5fLm1fQ0VfW21fcGF0dGVybl8ubV9DRUxlbmd0aF8gLSAxXTsKCSAgICAgICAgICAgICAgICB0YXJnZXRUZXh0LnNldEluZGV4KGVuZCk7CgkgICAgICAgICAgICAgICAgaWYgKFVURjE2LmlzVHJhaWxTdXJyb2dhdGUodGFyZ2V0VGV4dC5wcmV2aW91cygpKSkgewoJICAgICAgICAgICAgICAgIAlpZiAodGFyZ2V0VGV4dC5nZXRJbmRleCgpID4gbV90ZXh0QmVnaW5PZmZzZXRfICYmCgkgICAgICAgICAgICAgICAgCQkhVVRGMTYuaXNMZWFkU3Vycm9nYXRlKHRhcmdldFRleHQucHJldmlvdXMoKSkpIHsKCSAgICAgICAgICAgICAgICAJCXRhcmdldFRleHQubmV4dCgpOwoJICAgICAgICAgICAgICAgIAl9CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgIGVuZCA9IHRhcmdldFRleHQuZ2V0SW5kZXgoKTsKCSAgICAgICAgICAgICAgICBpZiAoKGdldEZDRCh0YXJnZXRUZXh0LCBlbmQpICYgTEFTVF9CWVRFX01BU0tfKSAhPSAwKSB7CgkgICAgICAgICAgICAgICAgICAgIGNlID0gZ2V0Q0UobV9jb2xFSXRlcl8ucHJldmlvdXMoKSk7CgkgICAgICAgICAgICAgICAgICAgIHdoaWxlIChjZSAhPSBleHBlY3RlZCAKCSAgICAgICAgICAgICAgICAgICAgCQkmJiBjZSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSIAoJICAgICAgICAgICAgICAgICAgICAJCSYmIG1fY29sRUl0ZXJfLmdldE9mZnNldCgpIDw9IHN0YXJ0KSB7CgkgICAgICAgICAgICAgICAgICAgICAgICBjZSA9IGdldENFKG1fY29sRUl0ZXJfLnByZXZpb3VzKCkpOwoJICAgICAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKGNlICE9IG1fcGF0dGVybl8ubV9DRV9bY291bnQgLSAxXSkgewoJICAgICAgICAgICAgICAgIHN0YXJ0IC0tOwoJICAgICAgICAgICAgICAgIHN0YXJ0ID0gZ2V0UHJldmlvdXNCYXNlT2Zmc2V0KHN0YXJ0KTsKCSAgICAgICAgICAgICAgICBtX3V0aWxCdWZmZXJfWzBdID0gc3RhcnQ7CgkgICAgICAgICAgICAgICAgbV91dGlsQnVmZmVyX1sxXSA9IGVuZDsKCSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBjb3VudCAtLTsKCSAgICAgICAgfQoJICAgIH0gCgkgICAgbV91dGlsQnVmZmVyX1swXSA9IHN0YXJ0OwoJICAgIG1fdXRpbEJ1ZmZlcl9bMV0gPSBlbmQ7CgkgICAgcmV0dXJuIHRydWU7Cgl9CgkKCS8qKgoJICogQ2hlY2tzIGFuZCBzZXRzIHRoZSBtYXRjaCBpbmZvcm1hdGlvbiBpZiBmb3VuZC4KCSAqIENoZWNrcyAKCSAqIDx1bD4KCSAqIDxsaT4gdGhlIHBvdGVudGlhbCBtYXRjaCBkb2VzIG5vdCByZXBlYXQgdGhlIHByZXZpb3VzIG1hdGNoCgkgKiA8bGk+IGJvdW5kYXJpZXMgYXJlIGNvcnJlY3QKCSAqIDxsaT4gcG90ZW50aWFsIG1hdGNoIGRvZXMgbm90IGVuZCBpbiB0aGUgbWlkZGxlIG9mIGEgY29udHJhY3Rpb24KCSAqIDxsaT4gaWRlbnRpY2FsIG1hdGNoZXMKCSAqIDwvdWw+CgkgKiBPdGhlcndpc2UgdGhlIG9mZnNldCB3aWxsIGJlIHNoaWZ0ZWQgdG8gdGhlIG5leHQgY2hhcmFjdGVyLgoJICogVXNlcyB0aGUgdGVtcG9yYXJ5IHV0aWxpdHkgYnVmZmVyIGZvciBzdG9yaW5nIHRoZSBtb2RpZmllZCB0ZXh0b2Zmc2V0LgoJICogQHBhcmFtIHRleHRvZmZzZXQgb2Zmc2V0IGluIHRoZSBjb2xsYXRpb24gZWxlbWVudCB0ZXh0LiB0aGUgcmV0dXJuZWQgCgkgKiAJCQl2YWx1ZSB3aWxsIGJlIHRoZSB0cnVuY2F0ZWQgc3RhcnQgb2Zmc2V0IG9mIHRoZSBtYXRjaCBvciB0aGUgCgkgKiAJCQluZXcgc3RhcnQgc2VhcmNoIG9mZnNldC4KCSAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbWF0Y2ggaXMgdmFsaWQsIGZhbHNlIG90aGVyd2lzZQoJICovCglwcml2YXRlIGJvb2xlYW4gY2hlY2tQcmV2aW91c0Nhbm9uaWNhbE1hdGNoKGludCB0ZXh0b2Zmc2V0KQoJewoJICAgIC8vIHRvIGVuc3VyZSB0aGF0IHRoZSBzdGFydCBhbmQgZW5kcyBhcmUgbm90IGNvbXBvc2l0ZSBjaGFyYWN0ZXJzCgkgICAgLy8gaWYgd2UgaGF2ZSBhIGNhbm9uaWNhbCBhY2NlbnQgbWF0Y2gKCSAgICBpZiAobV9wYXR0ZXJuXy5tX2hhc1N1ZmZpeEFjY2VudHNfIAoJICAgIAkmJiBtX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfLmxlbmd0aCgpICE9IDAgCgkgICAgCXx8IG1fcGF0dGVybl8ubV9oYXNQcmVmaXhBY2NlbnRzXyAKCSAgICAJJiYgbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5sZW5ndGgoKSAhPSAwKSB7CgkgICAgICAgIG1fbWF0Y2hlZEluZGV4XyA9IHRleHRvZmZzZXQ7CgkgICAgICAgIG1hdGNoTGVuZ3RoID0gZ2V0TmV4dEJhc2VPZmZzZXQobV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCkpIAoJICAgICAgICAgICAgCQkJCQkJCQkJCQkJLSB0ZXh0b2Zmc2V0OwoJICAgICAgICByZXR1cm4gdHJ1ZTsKCSAgICB9CgkKCSAgICBpbnQgZW5kID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CgkgICAgaWYgKCFjaGVja1ByZXZpb3VzQ2Fub25pY2FsQ29udHJhY3Rpb25NYXRjaCh0ZXh0b2Zmc2V0LCBlbmQpKSB7CgkgICAgCS8vIHN0b3JpbmcgdGhlIG1vZGlmaWVkIHRleHRvZmZzZXQKCSAgICAJcmV0dXJuIGZhbHNlOwoJICAgIH0KCSAgICB0ZXh0b2Zmc2V0ID0gbV91dGlsQnVmZmVyX1swXTsKCQllbmQgPSBtX3V0aWxCdWZmZXJfWzFdOwoJICAgIGVuZCA9IGdldE5leHRCYXNlT2Zmc2V0KGVuZCk7CgkgICAgLy8gdGhpcyB0b3RhbGx5IG1hdGNoZXMsIGhvd2V2ZXIgd2UgbmVlZCB0byBjaGVjayBpZiBpdCBpcyByZXBlYXRpbmcKCSAgICBpZiAoY2hlY2tSZXBlYXRlZE1hdGNoKHRleHRvZmZzZXQsIGVuZCkgCgkgICAgCXx8ICFpc0JyZWFrVW5pdCh0ZXh0b2Zmc2V0LCBlbmQpIAoJICAgIAl8fCAhY2hlY2tJZGVudGljYWwodGV4dG9mZnNldCwgZW5kKSkgewoJICAgICAgICB0ZXh0b2Zmc2V0IC0tOwoJICAgICAgICB0ZXh0b2Zmc2V0ID0gZ2V0UHJldmlvdXNCYXNlT2Zmc2V0KHRleHRvZmZzZXQpOwoJICAgICAgICBtX3V0aWxCdWZmZXJfWzBdID0gdGV4dG9mZnNldDsKCSAgICAgICAgcmV0dXJuIGZhbHNlOwoJICAgIH0KCSAgICAKCSAgICBtX21hdGNoZWRJbmRleF8gPSB0ZXh0b2Zmc2V0OwoJICAgIG1hdGNoTGVuZ3RoID0gZW5kIC0gdGV4dG9mZnNldDsKCSAgICByZXR1cm4gdHJ1ZTsKCX0KCQoJLyoqCgkgKiBNZXRob2QgdGhhdCBkb2VzIHRoZSBuZXh0IGV4YWN0IG1hdGNoCgkgKiBAcGFyYW0gc3RhcnQgdGhlIG9mZnNldCB0byBzdGFydCBzaGlmdGluZyBmcm9tIGFuZCBwZXJmb3JtaW5nIHRoZSAKCSAqICAgICAgICBuZXh0IGV4YWN0IG1hdGNoCgkgKi8KCXByaXZhdGUgdm9pZCBoYW5kbGVOZXh0RXhhY3QoaW50IHN0YXJ0KQoJewoJICAgCWludCB0ZXh0b2Zmc2V0ID0gc2hpZnRGb3J3YXJkKHN0YXJ0LCAKCSAgIAkJCQkJCQkJICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSLAoJICAgCQkJCQkJCQkgIG1fcGF0dGVybl8ubV9DRUxlbmd0aF8pOwoJCWludCB0YXJnZXRjZSA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEU7CgkgICAgd2hpbGUgKHRleHRvZmZzZXQgPD0gbV90ZXh0TGltaXRPZmZzZXRfKSB7CiAgICAgICAgICAgIAkgICAgCW1fY29sRUl0ZXJfLnNldEV4YWN0T2Zmc2V0KHRleHRvZmZzZXQpOwoJICAgICAgICBpbnQgcGF0dGVybmNlaW5kZXggPSBtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfIC0gMTsKCSAgICAgICAgYm9vbGVhbiBmb3VuZCA9IGZhbHNlOwoJICAgICAgICBpbnQgbGFzdGNlID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUjsKCSAgICAgICAgCgkgICAgICAgIHdoaWxlICh0cnVlKSB7CgkgICAgICAgICAgICAvLyBmaW5kaW5nIHRoZSBsYXN0IHBhdHRlcm4gY2UgbWF0Y2gsIGltYWdpbmUgY29tcG9zaXRlIAoJICAgICAgICAgICAgLy8gY2hhcmFjdGVycy4gZm9yIGV4YW1wbGU6IHNlYXJjaCBmb3IgcGF0dGVybiBBIGluIHRleHQgXHUwMEMwCgkgICAgICAgICAgICAvLyB3ZSdsbCBoYXZlIHRvIHNraXAgXHUwMzAwIHRoZSBncmF2ZSBmaXJzdCBiZWZvcmUgd2UgZ2V0IHRvIEEKCSAgICAgICAgICAgIHRhcmdldGNlID0gbV9jb2xFSXRlcl8ucHJldmlvdXMoKTsKCSAgICAgICAgICAgIGlmICh0YXJnZXRjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CgkgICAgICAgICAgICAgICAgZm91bmQgPSBmYWxzZTsKCSAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHRhcmdldGNlID0gZ2V0Q0UodGFyZ2V0Y2UpOwoJICAgICAgICAgICAgaWYgKHRhcmdldGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUgJiYgCgkgICAgICAgICAgICAJbV9jb2xFSXRlcl8uaXNJbkJ1ZmZlcigpKSB7IAoJICAgICAgICAgICAgICAgIC8vIHRoaXMgaXMgZm9yIHRoZSB0ZXh0IFx1MDMxNVx1MDMwMCB0aGF0IHJlcXVpcmVzIAoJICAgICAgICAgICAgICAgIC8vIG5vcm1hbGl6YXRpb24gYW5kIHBhdHRlcm4gXHUwMzAwLCB3aGVyZSBcdTAzMTUgaXMgaWdub3JhYmxlCgkgICAgICAgICAgICAgICAgY29udGludWU7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAobGFzdGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIgCgkgICAgICAgICAgICAJfHwgbGFzdGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgICAgICBsYXN0Y2UgPSB0YXJnZXRjZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGlmICh0YXJnZXRjZSA9PSBtX3BhdHRlcm5fLm1fQ0VfW3BhdHRlcm5jZWluZGV4XSkgewoJICAgICAgICAgICAgICAgIC8vIHRoZSBmaXJzdCBjZSBjYW4gYmUgYSBjb250cmFjdGlvbgoJICAgICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTsKCSAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGlmIChtX2NvbEVJdGVyXy5tX0NFQnVmZmVyT2Zmc2V0XyA8PSAwKSB7CgkgICAgICAgICAgICAgICAgZm91bmQgPSBmYWxzZTsKCSAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJCgkgICAgICAgIHRhcmdldGNlID0gbGFzdGNlOwoJICAgICAgICAKCSAgICAgICAgd2hpbGUgKGZvdW5kICYmIHBhdHRlcm5jZWluZGV4ID4gMCkgewoJICAgICAgICAgICAgdGFyZ2V0Y2UgPSBtX2NvbEVJdGVyXy5wcmV2aW91cygpOwoJICAgICAgICAgICAgaWYgKHRhcmdldGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKCSAgICAgICAgICAgICAgICBmb3VuZCA9IGZhbHNlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgdGFyZ2V0Y2UgPSBnZXRDRSh0YXJnZXRjZSk7CgkgICAgICAgICAgICBpZiAodGFyZ2V0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICAgICAgfQoJCgkgICAgICAgICAgICBwYXR0ZXJuY2VpbmRleCAtLTsKCSAgICAgICAgICAgIGZvdW5kID0gZm91bmQgJiYgdGFyZ2V0Y2UgPT0gbV9wYXR0ZXJuXy5tX0NFX1twYXR0ZXJuY2VpbmRleF07IAoJICAgICAgICB9CgkKCSAgICAgICAgaWYgKCFmb3VuZCkgewoJICAgICAgICAgICAgdGV4dG9mZnNldCA9IHNoaWZ0Rm9yd2FyZCh0ZXh0b2Zmc2V0LCB0YXJnZXRjZSwgCgkgICAgICAgICAgICAJCQkJCQkJCQkJCXBhdHRlcm5jZWluZGV4KTsKCSAgICAgICAgICAgIC8vIHN0YXR1cyBjaGVja2VkIGF0IGxvb3AuCgkgICAgICAgICAgICBwYXR0ZXJuY2VpbmRleCA9IG1fcGF0dGVybl8ubV9DRUxlbmd0aF87CgkgICAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgfQoJICAgICAgICAKCSAgICAgICAgaWYgKGNoZWNrTmV4dEV4YWN0TWF0Y2godGV4dG9mZnNldCkpIHsKCSAgICAgICAgICAgIC8vIHN0YXR1cyBjaGVja2VkIGluIHVjb2xfc2V0T2Zmc2V0CgkgICAgICAgICAgICByZXR1cm47CgkgICAgICAgIH0KCSAgICAgICAgdGV4dG9mZnNldCA9IG1fdXRpbEJ1ZmZlcl9bMF07CgkgICAgfQoJICAgIHNldE1hdGNoTm90Rm91bmQoKTsKCX0KCgkvKioKCSAqIE1ldGhvZCB0aGF0IGRvZXMgdGhlIG5leHQgY2Fub25pY2FsIG1hdGNoCgkgKiBAcGFyYW0gc3RhcnQgdGhlIG9mZnNldCB0byBzdGFydCBzaGlmdGluZyBmcm9tIGFuZCBwZXJmb3JtaW5nIHRoZSAKCSAqICAgICAgICBuZXh0IGNhbm9uaWNhbCBtYXRjaAoJICovCglwcml2YXRlIHZvaWQgaGFuZGxlTmV4dENhbm9uaWNhbChpbnQgc3RhcnQpCgl7CgkgICAgYm9vbGVhbiBoYXNQYXR0ZXJuQWNjZW50cyA9IAoJICAgICAgIG1fcGF0dGVybl8ubV9oYXNTdWZmaXhBY2NlbnRzXyB8fCBtX3BhdHRlcm5fLm1faGFzUHJlZml4QWNjZW50c187CgkgICAgICAgICAgCgkgICAgLy8gc2hpZnRpbmcgaXQgY2hlY2sgZm9yIHNldHRpbmcgb2Zmc2V0CgkgICAgLy8gaWYgc2V0T2Zmc2V0IGlzIGNhbGxlZCBwcmV2aW91c2x5IG9yIHRoZXJlIHdhcyBubyBwcmV2aW91cyBtYXRjaCwgd2UKCSAgICAvLyBsZWF2ZSB0aGUgb2Zmc2V0IGFzIGl0IGlzLgoJICAgIGludCB0ZXh0b2Zmc2V0ID0gc2hpZnRGb3J3YXJkKHN0YXJ0LCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSLCAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAkgIG1fcGF0dGVybl8ubV9DRUxlbmd0aF8pOwoJICAgIG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18uZGVsZXRlKDAsIG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18ubGVuZ3RoKCkpOwoJICAgIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18uZGVsZXRlKDAsIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18ubGVuZ3RoKCkpOwoJCWludCB0YXJnZXRjZSA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEU7CgkgICAgCgkgICAgd2hpbGUgKHRleHRvZmZzZXQgPD0gbV90ZXh0TGltaXRPZmZzZXRfKQoJICAgIHsKCSAgICAJbV9jb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQodGV4dG9mZnNldCk7CgkgICAgICAgIGludCBwYXR0ZXJuY2VpbmRleCA9IG1fcGF0dGVybl8ubV9DRUxlbmd0aF8gLSAxOwoJICAgICAgICBib29sZWFuIGZvdW5kID0gZmFsc2U7CgkgICAgICAgIGludCBsYXN0Y2UgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSOwoJICAgICAgICAKCSAgICAgICAgd2hpbGUgKHRydWUpIHsKCSAgICAgICAgICAgIC8vIGZpbmRpbmcgdGhlIGxhc3QgcGF0dGVybiBjZSBtYXRjaCwgaW1hZ2luZSBjb21wb3NpdGUgY2hhcmFjdGVycwoJICAgICAgICAgICAgLy8gZm9yIGV4YW1wbGU6IHNlYXJjaCBmb3IgcGF0dGVybiBBIGluIHRleHQgXHUwMEMwCgkgICAgICAgICAgICAvLyB3ZSdsbCBoYXZlIHRvIHNraXAgXHUwMzAwIHRoZSBncmF2ZSBmaXJzdCBiZWZvcmUgd2UgZ2V0IHRvIEEKCSAgICAgICAgICAgIHRhcmdldGNlID0gbV9jb2xFSXRlcl8ucHJldmlvdXMoKTsKCSAgICAgICAgICAgIGlmICh0YXJnZXRjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CgkgICAgICAgICAgICAgICAgZm91bmQgPSBmYWxzZTsKCSAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHRhcmdldGNlID0gZ2V0Q0UodGFyZ2V0Y2UpOwoJICAgICAgICAgICAgaWYgKGxhc3RjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSIAoJICAgICAgICAgICAgCQkJfHwgbGFzdGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgICAgICBsYXN0Y2UgPSB0YXJnZXRjZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGlmICh0YXJnZXRjZSA9PSBtX3BhdHRlcm5fLm1fQ0VfW3BhdHRlcm5jZWluZGV4XSkgewoJICAgICAgICAgICAgICAgIC8vIHRoZSBmaXJzdCBjZSBjYW4gYmUgYSBjb250cmFjdGlvbgoJICAgICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTsKCSAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGlmIChtX2NvbEVJdGVyXy5tX0NFQnVmZmVyT2Zmc2V0XyA8PSAwKSB7CgkgICAgICAgICAgICAgICAgZm91bmQgPSBmYWxzZTsKCSAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgICAgICB0YXJnZXRjZSA9IGxhc3RjZTsKCSAgICAgICAgCgkgICAgICAgIHdoaWxlIChmb3VuZCAmJiBwYXR0ZXJuY2VpbmRleCA+IDApIHsKCSAgICAgICAgICAgIHRhcmdldGNlICAgID0gbV9jb2xFSXRlcl8ucHJldmlvdXMoKTsKCSAgICAgICAgICAgIGlmICh0YXJnZXRjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CgkgICAgICAgICAgICAgICAgZm91bmQgPSBmYWxzZTsKCSAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHRhcmdldGNlICAgID0gZ2V0Q0UodGFyZ2V0Y2UpOwoJICAgICAgICAgICAgaWYgKHRhcmdldGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgICAgIH0KCQoJICAgICAgICAgICAgcGF0dGVybmNlaW5kZXggLS07CgkgICAgICAgICAgICBmb3VuZCA9IGZvdW5kICYmIHRhcmdldGNlID09IG1fcGF0dGVybl8ubV9DRV9bcGF0dGVybmNlaW5kZXhdOyAKCSAgICAgICAgfQoJCgkgICAgICAgIC8vIGluaXRpYWxpemluZyB0aGUgcmVhcnJhbmdlZCBhY2NlbnQgYXJyYXkKCSAgICAgICAgaWYgKGhhc1BhdHRlcm5BY2NlbnRzICYmICFmb3VuZCkgewoJICAgICAgICAgICAgZm91bmQgPSBkb05leHRDYW5vbmljYWxNYXRjaCh0ZXh0b2Zmc2V0KTsKCSAgICAgICAgfQoJCgkgICAgICAgIGlmICghZm91bmQpIHsKCSAgICAgICAgICAgIHRleHRvZmZzZXQgPSBzaGlmdEZvcndhcmQodGV4dG9mZnNldCwgdGFyZ2V0Y2UsIHBhdHRlcm5jZWluZGV4KTsKCSAgICAgICAgICAgIC8vIHN0YXR1cyBjaGVja2VkIGF0IGxvb3AKCSAgICAgICAgICAgIHBhdHRlcm5jZWluZGV4ID0gbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXzsKCSAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICB9CgkgICAgICAgIAoJICAgICAgICBpZiAoY2hlY2tOZXh0Q2Fub25pY2FsTWF0Y2godGV4dG9mZnNldCkpIHsKCSAgICAgICAgICAgIHJldHVybjsKCSAgICAgICAgfQoJICAgICAgICB0ZXh0b2Zmc2V0ID0gbV91dGlsQnVmZmVyX1swXTsKCSAgICB9CgkgICAgc2V0TWF0Y2hOb3RGb3VuZCgpOwoJfQoJCgkvKioKCSAqIE1ldGhvZCB0aGF0IGRvZXMgdGhlIHByZXZpb3VzIGV4YWN0IG1hdGNoCgkgKiBAcGFyYW0gc3RhcnQgdGhlIG9mZnNldCB0byBzdGFydCBzaGlmdGluZyBmcm9tIGFuZCBwZXJmb3JtaW5nIHRoZSAKCSAqICAgICAgICBwcmV2aW91cyBleGFjdCBtYXRjaAoJICovCglwcml2YXRlIHZvaWQgaGFuZGxlUHJldmlvdXNFeGFjdChpbnQgc3RhcnQpCgl7CgkgICAgaW50IHRleHRvZmZzZXQgPSByZXZlcnNlU2hpZnQoc3RhcnQsIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIsIAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fcGF0dGVybl8ubV9DRUxlbmd0aF8pOwoJICAgIHdoaWxlICh0ZXh0b2Zmc2V0ID49IG1fdGV4dEJlZ2luT2Zmc2V0XykKCSAgICB7CgkgICAgCW1fY29sRUl0ZXJfLnNldEV4YWN0T2Zmc2V0KHRleHRvZmZzZXQpOwoJICAgICAgICBpbnQgcGF0dGVybmNlaW5kZXggPSAxOwoJICAgICAgICBpbnQgdGFyZ2V0Y2UgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFOwoJICAgICAgICBib29sZWFuIGZvdW5kID0gZmFsc2U7CgkgICAgICAgIGludCBmaXJzdGNlID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUjsKCSAgICAgICAgCgkgICAgICAgIHdoaWxlICh0cnVlKSB7CgkgICAgICAgICAgICAvLyBmaW5kaW5nIHRoZSBmaXJzdCBwYXR0ZXJuIGNlIG1hdGNoLCBpbWFnaW5lIGNvbXBvc2l0ZSAKCSAgICAgICAgICAgIC8vIGNoYXJhY3RlcnMuIGZvciBleGFtcGxlOiBzZWFyY2ggZm9yIHBhdHRlcm4gXHUwMzAwIGluIHRleHQgCgkgICAgICAgICAgICAvLyBcdTAwQzAsIHdlJ2xsIGhhdmUgdG8gc2tpcCBBIGZpcnN0IGJlZm9yZSB3ZSBnZXQgdG8gCgkgICAgICAgICAgICAvLyBcdTAzMDAgdGhlIGdyYXZlIGFjY2VudAoJICAgICAgICAgICAgdGFyZ2V0Y2UgPSBtX2NvbEVJdGVyXy5uZXh0KCk7CgkgICAgICAgICAgICBpZiAodGFyZ2V0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewoJICAgICAgICAgICAgICAgIGZvdW5kID0gZmFsc2U7CgkgICAgICAgICAgICAgICAgYnJlYWs7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICB0YXJnZXRjZSA9IGdldENFKHRhcmdldGNlKTsKCSAgICAgICAgICAgIGlmIChmaXJzdGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIgCgkgICAgICAgICAgICAJfHwgZmlyc3RjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CgkgICAgICAgICAgICAgICAgZmlyc3RjZSA9IHRhcmdldGNlOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKHRhcmdldGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgICAgIH0gICAgICAgICAKCSAgICAgICAgICAgIGlmICh0YXJnZXRjZSA9PSBtX3BhdHRlcm5fLm1fQ0VfWzBdKSB7CgkgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJPZmZzZXRfID09IC0xIAoJICAgICAgICAgICAgCXx8IG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJPZmZzZXRfIAoJICAgICAgICAgICAgCQkJCQkJCT09IG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJTaXplXykgewoJICAgICAgICAgICAgICAgIC8vIGNoZWNraW5nIGZvciBhY2NlbnRzIGluIGNvbXBvc2l0ZSBjaGFyYWN0ZXIKCSAgICAgICAgICAgICAgICBmb3VuZCA9IGZhbHNlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkKCSAgICAgICAgdGFyZ2V0Y2UgPSBmaXJzdGNlOwoJICAgICAgICAKCSAgICAgICAgd2hpbGUgKGZvdW5kICYmIHBhdHRlcm5jZWluZGV4IDwgbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXykgewoJICAgICAgICAgICAgdGFyZ2V0Y2UgPSBtX2NvbEVJdGVyXy5uZXh0KCk7CgkgICAgICAgICAgICBpZiAodGFyZ2V0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewoJICAgICAgICAgICAgICAgIGZvdW5kID0gZmFsc2U7CgkgICAgICAgICAgICAgICAgYnJlYWs7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICB0YXJnZXRjZSA9IGdldENFKHRhcmdldGNlKTsKCSAgICAgICAgICAgIGlmICh0YXJnZXRjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CgkgICAgICAgICAgICAgICAgY29udGludWU7CgkgICAgICAgICAgICB9CgkKCSAgICAgICAgICAgIGZvdW5kID0gZm91bmQgJiYgdGFyZ2V0Y2UgPT0gbV9wYXR0ZXJuXy5tX0NFX1twYXR0ZXJuY2VpbmRleF07IAoJICAgICAgICAgICAgcGF0dGVybmNlaW5kZXggKys7CgkgICAgICAgIH0KCQoJICAgICAgICBpZiAoIWZvdW5kKSB7CgkgICAgICAgICAgICB0ZXh0b2Zmc2V0ID0gcmV2ZXJzZVNoaWZ0KHRleHRvZmZzZXQsIHRhcmdldGNlLCBwYXR0ZXJuY2VpbmRleCk7CgkgICAgICAgICAgICBwYXR0ZXJuY2VpbmRleCA9IDA7CgkgICAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgfQoJICAgICAgICAKCSAgICAgICAgaWYgKGNoZWNrUHJldmlvdXNFeGFjdE1hdGNoKHRleHRvZmZzZXQpKSB7CgkgICAgICAgICAgICByZXR1cm47CgkgICAgICAgIH0KCSAgICAgICAgdGV4dG9mZnNldCA9IG1fdXRpbEJ1ZmZlcl9bMF07CgkgICAgfQoJICAgIHNldE1hdGNoTm90Rm91bmQoKTsKCX0KCQoJLyoqCgkgKiBNZXRob2QgdGhhdCBkb2VzIHRoZSBwcmV2aW91cyBjYW5vbmljYWwgbWF0Y2gKCSAqIEBwYXJhbSBzdGFydCB0aGUgb2Zmc2V0IHRvIHN0YXJ0IHNoaWZ0aW5nIGZyb20gYW5kIHBlcmZvcm1pbmcgdGhlIAoJICogICAgICAgIHByZXZpb3VzIGNhbm9uaWNhbCBtYXRjaAoJICovCglwcml2YXRlIHZvaWQgaGFuZGxlUHJldmlvdXNDYW5vbmljYWwoaW50IHN0YXJ0KQoJewoJICAgIGJvb2xlYW4gaGFzUGF0dGVybkFjY2VudHMgPSAKCSAgICAgICBtX3BhdHRlcm5fLm1faGFzU3VmZml4QWNjZW50c18gfHwgbV9wYXR0ZXJuXy5tX2hhc1ByZWZpeEFjY2VudHNfOwoJICAgICAgICAgIAoJICAgIC8vIHNoaWZ0aW5nIGl0IGNoZWNrIGZvciBzZXR0aW5nIG9mZnNldAoJICAgIC8vIGlmIHNldE9mZnNldCBpcyBjYWxsZWQgcHJldmlvdXNseSBvciB0aGVyZSB3YXMgbm8gcHJldmlvdXMgbWF0Y2gsIHdlCgkgICAgLy8gbGVhdmUgdGhlIG9mZnNldCBhcyBpdCBpcy4KCSAgICBpbnQgdGV4dG9mZnNldCA9IHJldmVyc2VTaGlmdChzdGFydCwgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUiwgCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAJCW1fcGF0dGVybl8ubV9DRUxlbmd0aF8pOwoJICAgIG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18uZGVsZXRlKDAsIG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18ubGVuZ3RoKCkpOwoJICAgIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18uZGVsZXRlKDAsIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18ubGVuZ3RoKCkpOwoJICAgIAoJICAgIHdoaWxlICh0ZXh0b2Zmc2V0ID49IG1fdGV4dEJlZ2luT2Zmc2V0XykKCSAgICB7CgkgICAgCW1fY29sRUl0ZXJfLnNldEV4YWN0T2Zmc2V0KHRleHRvZmZzZXQpOwoJICAgICAgICBpbnQgcGF0dGVybmNlaW5kZXggPSAxOwoJICAgICAgICBpbnQgdGFyZ2V0Y2UgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFOwoJICAgICAgICBib29sZWFuIGZvdW5kID0gZmFsc2U7CgkgICAgICAgIGludCBmaXJzdGNlID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUjsKCSAgICAgICAgCgkgICAgICAgIHdoaWxlICh0cnVlKSB7CgkgICAgICAgICAgICAvLyBmaW5kaW5nIHRoZSBmaXJzdCBwYXR0ZXJuIGNlIG1hdGNoLCBpbWFnaW5lIGNvbXBvc2l0ZSAKCSAgICAgICAgICAgIC8vIGNoYXJhY3RlcnMuIGZvciBleGFtcGxlOiBzZWFyY2ggZm9yIHBhdHRlcm4gXHUwMzAwIGluIHRleHQgCgkgICAgICAgICAgICAvLyBcdTAwQzAsIHdlJ2xsIGhhdmUgdG8gc2tpcCBBIGZpcnN0IGJlZm9yZSB3ZSBnZXQgdG8gCgkgICAgICAgICAgICAvLyBcdTAzMDAgdGhlIGdyYXZlIGFjY2VudAoJICAgICAgICAgICAgdGFyZ2V0Y2UgPSBtX2NvbEVJdGVyXy5uZXh0KCk7CgkgICAgICAgICAgICBpZiAodGFyZ2V0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewoJICAgICAgICAgICAgICAgIGZvdW5kID0gZmFsc2U7CgkgICAgICAgICAgICAgICAgYnJlYWs7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICB0YXJnZXRjZSA9IGdldENFKHRhcmdldGNlKTsKCSAgICAgICAgICAgIGlmIChmaXJzdGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIgCgkgICAgICAgICAgICAJfHwgZmlyc3RjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CgkgICAgICAgICAgICAgICAgZmlyc3RjZSA9IHRhcmdldGNlOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgCgkgICAgICAgICAgICBpZiAodGFyZ2V0Y2UgPT0gbV9wYXR0ZXJuXy5tX0NFX1swXSkgewoJICAgICAgICAgICAgICAgIC8vIHRoZSBmaXJzdCBjZSBjYW4gYmUgYSBjb250cmFjdGlvbgoJICAgICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTsKCSAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGlmIChtX2NvbEVJdGVyXy5tX0NFQnVmZmVyT2Zmc2V0XyA9PSAtMSAKCSAgICAgICAgICAgIAl8fCBtX2NvbEVJdGVyXy5tX0NFQnVmZmVyT2Zmc2V0XyAKCSAgICAgICAgICAgIAkJCQkJCQk9PSBtX2NvbEVJdGVyXy5tX0NFQnVmZmVyU2l6ZV8pIHsKCSAgICAgICAgICAgICAgICAvLyBjaGVja2luZyBmb3IgYWNjZW50cyBpbiBjb21wb3NpdGUgY2hhcmFjdGVyCgkgICAgICAgICAgICAgICAgZm91bmQgPSBmYWxzZTsKCSAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJCgkgICAgICAgIHRhcmdldGNlID0gZmlyc3RjZTsKCSAgICAgICAgCgkgICAgICAgIHdoaWxlIChmb3VuZCAmJiBwYXR0ZXJuY2VpbmRleCA8IG1fcGF0dGVybl8ubV9DRUxlbmd0aF8pIHsKCSAgICAgICAgICAgIHRhcmdldGNlID0gbV9jb2xFSXRlcl8ubmV4dCgpOwoJICAgICAgICAgICAgaWYgKHRhcmdldGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKCSAgICAgICAgICAgICAgICBmb3VuZCA9IGZhbHNlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgdGFyZ2V0Y2UgPSBnZXRDRSh0YXJnZXRjZSk7CgkgICAgICAgICAgICBpZiAodGFyZ2V0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICAgICAgfQoJCgkgICAgICAgICAgICBmb3VuZCA9IGZvdW5kICYmIHRhcmdldGNlID09IG1fcGF0dGVybl8ubV9DRV9bcGF0dGVybmNlaW5kZXhdOyAKCSAgICAgICAgICAgIHBhdHRlcm5jZWluZGV4ICsrOwoJICAgICAgICB9CgkKCSAgICAgICAgLy8gaW5pdGlhbGl6aW5nIHRoZSByZWFycmFuZ2VkIGFjY2VudCBhcnJheQoJICAgICAgICBpZiAoaGFzUGF0dGVybkFjY2VudHMgJiYgIWZvdW5kKSB7CgkgICAgICAgICAgICBmb3VuZCA9IGRvUHJldmlvdXNDYW5vbmljYWxNYXRjaCh0ZXh0b2Zmc2V0KTsKCSAgICAgICAgfQoJCgkgICAgICAgIGlmICghZm91bmQpIHsKCSAgICAgICAgICAgIHRleHRvZmZzZXQgPSByZXZlcnNlU2hpZnQodGV4dG9mZnNldCwgdGFyZ2V0Y2UsIHBhdHRlcm5jZWluZGV4KTsKCSAgICAgICAgICAgIHBhdHRlcm5jZWluZGV4ID0gMDsKCSAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICB9CgkKCSAgICAgICAgaWYgKGNoZWNrUHJldmlvdXNDYW5vbmljYWxNYXRjaCh0ZXh0b2Zmc2V0KSkgewoJICAgICAgICAgICAgcmV0dXJuOwoJICAgICAgICB9CgkgICAgICAgIHRleHRvZmZzZXQgPSBtX3V0aWxCdWZmZXJfWzBdOwoJICAgIH0KCSAgICBzZXRNYXRjaE5vdEZvdW5kKCk7Cgl9CgkKCS8qKgoJICogR2V0cyBhIHN1YnN0cmluZyBvdXQgb2YgYSBDaGFyYWN0ZXJJdGVyYXRvcgoJICogQHBhcmFtIHRleHQgQ2hhcmFjdGVySXRlcmF0b3IKCSAqIEBwYXJhbSBzdGFydCBzdGFydCBvZmZzZXQKCSAqIEBwYXJhbSBsZW5ndGggb2Ygc3Vic3RyaW5nCgkgKiBAcmV0dXJuIHN1YnN0cmluZyBmcm9tIHRleHQgc3RhcnRpbmcgYXQgc3RhcnQgYW5kIGxlbmd0aCBsZW5ndGgKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIGdldFN0cmluZyhDaGFyYWN0ZXJJdGVyYXRvciB0ZXh0LCBpbnQgc3RhcnQsCgkJCQkJCQkJCQkJaW50IGxlbmd0aCkKCXsKCQlTdHJpbmdCdWZmZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1ZmZlcihsZW5ndGgpOwoJCWludCBvZmZzZXQgPSB0ZXh0LmdldEluZGV4KCk7CgkJdGV4dC5zZXRJbmRleChzdGFydCk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKyspIHsKCQkJcmVzdWx0LmFwcGVuZCh0ZXh0LmN1cnJlbnQoKSk7CgkJCXRleHQubmV4dCgpOwoJCX0KCQl0ZXh0LnNldEluZGV4KG9mZnNldCk7CgkJcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOwoJfQoJCgkvKioKCSAqIEdldHRpbmcgdGhlIG1hc2sgZm9yIGNvbGxhdGlvbiBzdHJlbmd0aAoJICogQHBhcmFtIHN0cmVuZ3RoIGNvbGxhdGlvbiBzdHJlbmd0aAogCSAqIEByZXR1cm4gY29sbGF0aW9uIGVsZW1lbnQgbWFzawoJICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgZ2V0TWFzayhpbnQgc3RyZW5ndGgpIAoJewoJICAgIHN3aXRjaCAoc3RyZW5ndGgpIAoJICAgIHsKCSAgICAJY2FzZSBDb2xsYXRvci5QUklNQVJZOgoJICAgICAgICAJcmV0dXJuIFJ1bGVCYXNlZENvbGxhdG9yLkNFX1BSSU1BUllfTUFTS187CgkgICAgCWNhc2UgQ29sbGF0b3IuU0VDT05EQVJZOgoJICAgICAgICAJcmV0dXJuIFJ1bGVCYXNlZENvbGxhdG9yLkNFX1NFQ09OREFSWV9NQVNLXyAKCSAgICAgICAgCSAgICAgICB8IFJ1bGVCYXNlZENvbGxhdG9yLkNFX1BSSU1BUllfTUFTS187CgkgICAgCWRlZmF1bHQ6CgkgICAgICAgIAlyZXR1cm4gUnVsZUJhc2VkQ29sbGF0b3IuQ0VfVEVSVElBUllfTUFTS18gCgkgICAgICAgIAkgICAgICAgfCBSdWxlQmFzZWRDb2xsYXRvci5DRV9TRUNPTkRBUllfTUFTS18gCgkgICAgICAgICAgICAgICAgICAgfCBSdWxlQmFzZWRDb2xsYXRvci5DRV9QUklNQVJZX01BU0tfOwoJICAgIH0KCX0KICAgIAogICAgLyoqCiAgICAgKiBTZXRzIG1hdGNoIG5vdCBmb3VuZCAKICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIHNldE1hdGNoTm90Rm91bmQoKSAKICAgIHsKICAgICAgICAvLyB0aGlzIG1ldGhvZCByZXNldHMgdGhlIG1hdGNoIHJlc3VsdCByZWdhcmRsZXNzIG9mIHRoZSBlcnJvciBzdGF0dXMuCiAgICAgICAgbV9tYXRjaGVkSW5kZXhfID0gRE9ORTsKICAgICAgICBzZXRNYXRjaExlbmd0aCgwKTsKICAgIH0KfQo=