LyoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChDKSAxOTk2LTIwMDAsIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kICAgICoKICogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogJFNvdXJjZTogL3hzcmwvTnN2bi9pY3UvaWN1NGovc3JjL2NvbS9pYm0vaWN1L3RleHQvU3RyaW5nU2VhcmNoLmphdmEsdiAkIAogKiAkRGF0ZTogMjAwMy8wNS8xNCAxOTowMzozMSAkIAogKiAkUmV2aXNpb246IDEuMjEgJAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICovCgpwYWNrYWdlIGNvbS5pYm0uaWN1LnRleHQ7CgppbXBvcnQgamF2YS50ZXh0LkNoYXJhY3Rlckl0ZXJhdG9yOwppbXBvcnQgamF2YS50ZXh0LlN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKaW1wb3J0IGNvbS5pYm0uaWN1LmxhbmcuVUNoYXJhY3RlcjsKaW1wb3J0IGNvbS5pYm0uaWN1LmltcGwuTm9ybWFsaXplckltcGw7CgovKioKICogPHA+CiAqIDxjb2RlPlN0cmluZ1NlYXJjaDwvY29kZT4gaXMgdGhlIGNvbmNyZXRlIHN1YmNsYXNzIG9mIAogKiA8Y29kZT5TZWFyY2hJdGVyYXRvcjwvY29kZT4gdGhhdCBwcm92aWRlcyBsYW5ndWFnZS1zZW5zaXRpdmUgdGV4dCBzZWFyY2hpbmcgCiAqIGJhc2VkIG9uIHRoZSBjb21wYXJpc29uIHJ1bGVzIGRlZmluZWQgaW4gYSB7QGxpbmsgUnVsZUJhc2VkQ29sbGF0b3J9IG9iamVjdC4KICogPC9wPgogKiA8cD4KICogPGNvZGU+U3RyaW5nU2VhcmNoPC9jb2RlPiB1c2VzIGEgdmVyc2lvbiBvZiB0aGUgZmFzdCBCb3llci1Nb29yZSBzZWFyY2gKICogYWxnb3JpdGhtIHRoYXQgaGFzIGJlZW4gYWRhcHRlZCB0byB3b3JrIHdpdGggdGhlIGxhcmdlIGNoYXJhY3RlciBzZXQgb2YKICogVW5pY29kZS4gUmVmZXIgdG8gCiAqIDxhIGhyZWY9aHR0cDovL29zcy5zb2Z0d2FyZS5pYm0uY29tL2ljdS9kb2NzL3BhcGVycy9lZmZpY2llbnRfdGV4dF9zZWFyY2hpbmdfaW5famF2YS5odG1sPgogKiAiRWZmaWNpZW50IFRleHQgU2VhcmNoaW5nIGluIEphdmEiPC9hPiwgcHVibGlzaGVkIGluIHRoZSAKICogPGk+SmF2YSBSZXBvcnQ8L2k+IG9uIEZlYnJ1YXJ5LCAxOTk5LCBmb3IgZnVydGhlciBpbmZvcm1hdGlvbiBvbiB0aGUgCiAqIGFsZ29yaXRobS4KICogPC9wPgogKiA8cD4KICogVXNlcnMgYXJlIGFsc28gc3Ryb25nbHkgZW5jb3VyYWdlZCB0byByZWFkIHRoZSBzZWN0aW9uIG9uIAogKiA8YSBocmVmPWh0dHA6Ly9vc3Muc29mdHdhcmUuaWJtLmNvbS9pY3UvdXNlcmd1aWRlL3NlYXJjaFN0cmluZy5odG1sPgogKiBTdHJpbmcgU2VhcmNoPC9hPiBhbmQgCiAqIDxhIGhyZWY9aHR0cDovL29zcy5zb2Z0d2FyZS5pYm0uY29tL2ljdS91c2VyZ3VpZGUvQ29sbGF0ZV9JbnRyby5odG1sPgogKiBDb2xsYXRpb248L2E+IGluIHRoZSB1c2VyIGd1aWRlIGJlZm9yZSBhdHRlbXB0aW5nIHRvIHVzZSB0aGlzIGNsYXNzLgogKiA8L3A+CiAqIDxwPgogKiBTdHJpbmcgc2VhcmNoaW5nIGdldHMgYWxpdHRsZSBjb21wbGljYXRlZCB3aGVuIGFjY2VudHMgYXJlIGVuY291bnRlcmVkIGF0CiAqIG1hdGNoIGJvdW5kYXJpZXMuIElmIGEgbWF0Y2ggaXMgZm91bmQgYW5kIGl0IGhhcyBwcmVjZWRpbmcgb3IgdHJhaWxpbmcgCiAqIGFjY2VudHMgbm90IHBhcnQgb2YgdGhlIG1hdGNoLCB0aGUgcmVzdWx0IHJldHVybmVkIHdpbGwgaW5jbHVkZSB0aGUgCiAqIHByZWNlZGluZyBhY2NlbnRzIHVwIHRvIHRoZSBmaXJzdCBiYXNlIGNoYXJhY3RlciwgaWYgdGhlIHBhdHRlcm4gc2VhcmNoZWQgCiAqIGZvciBzdGFydHMgYW4gYWNjZW50LiBMaWtld2lzZSwgCiAqIGlmIHRoZSBwYXR0ZXJuIGVuZHMgd2l0aCBhbiBhY2NlbnQsIGFsbCB0cmFpbGluZyBhY2NlbnRzIHVwIHRvIHRoZSBmaXJzdAogKiBiYXNlIGNoYXJhY3RlciB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSByZXN1bHQuCiAqIDwvcD4KICogPHA+CiAqIEZvciBleGFtcGxlLCBpZiBhIG1hdGNoIGlzIGZvdW5kIGluIHRhcmdldCB0ZXh0ICJhJiM5Mjt1MDMyNSYjOTI7dTAzMDAiIGZvciAKICogdGhlIHBhdHRlcm4KICogImEmIzkyO3UwMzI1IiwgdGhlIHJlc3VsdCByZXR1cm5lZCBieSBTdHJpbmdTZWFyY2ggd2lsbCBiZSB0aGUgaW5kZXggMCBhbmQKICogbGVuZ3RoIDMgJmx0OzAsIDMmZ3Q7LiBJZiBhIG1hdGNoIGlzIGZvdW5kIGluIHRoZSB0YXJnZXQgCiAqICJhJiM5Mjt1MDMyNSYjOTI7dTAzMDAiIAogKiBmb3IgdGhlIHBhdHRlcm4gIiYjOTI7dTAzMDAiLCB0aGVuIHRoZSByZXN1bHQgd2lsbCBiZSBpbmRleCAxIGFuZCBsZW5ndGggMiAKICogPDEsIDI+LgogKiA8L3A+CiAqIDxwPgogKiBJbiB0aGUgY2FzZSB3aGVyZSB0aGUgZGVjb21wb3NpdGlvbiBtb2RlIGlzIG9uIGZvciB0aGUgUnVsZUJhc2VkQ29sbGF0b3IsCiAqIGFsbCBtYXRjaGVzIHRoYXQgc3RhcnRzIG9yIGVuZHMgd2l0aCBhbiBhY2NlbnQgd2lsbCBoYXZlIGl0cyByZXN1bHRzIGluY2x1ZGUgCiAqIHByZWNlZGluZyBvciBmb2xsb3dpbmcgYWNjZW50cyByZXNwZWN0aXZlbHkuIEZvciBleGFtcGxlLCBpZiBwYXR0ZXJuICJhIiBpcwogKiBsb29rZWQgZm9yIGluIHRoZSB0YXJnZXQgdGV4dCAiJmFhY3V0ZTsmIzkyO3UwMzI1IiwgdGhlIHJlc3VsdCB3aWxsIGJlCiAqIGluZGV4IDAgYW5kIGxlbmd0aCAyICZsdDswLCAyJmd0Oy4KICogPC9wPgogKiA8cD4KICogVGhlIFN0cmluZ1NlYXJjaCBjbGFzcyBwcm92aWRlcyB0d28gb3B0aW9ucyB0byBoYW5kbGUgYWNjZW50IG1hdGNoaW5nIAogKiBkZXNjcmliZWQgYmVsb3c6CiAqIDwvcD4KICogPHA+CiAqIExldCBTJyBiZSB0aGUgc3ViLXN0cmluZyBvZiBhIHRleHQgc3RyaW5nIFMgYmV0d2VlbiB0aGUgb2Zmc2V0cyBzdGFydCBhbmQgCiAqIGVuZCAmbHQ7c3RhcnQsIGVuZCZndDsuCiAqIDxicj4KICogQSBwYXR0ZXJuIHN0cmluZyBQIG1hdGNoZXMgYSB0ZXh0IHN0cmluZyBTIGF0IHRoZSBvZmZzZXRzICZsdDtzdGFydCwgCiAqIGxlbmd0aCZndDsgCiAqIDxicj4KICogaWYKICogPHByZT4gCiAqIG9wdGlvbiAxLiBQIG1hdGNoZXMgc29tZSBjYW5vbmljYWwgZXF1aXZhbGVudCBzdHJpbmcgb2YgUycuIFN1cHBvc2UgdGhlIAogKiAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IgdXNlZCBmb3Igc2VhcmNoaW5nIGhhcyBhIGNvbGxhdGlvbiBzdHJlbmd0aCBvZiAKICogICAgICAgICAgIFRFUlRJQVJZLCBhbGwgYWNjZW50cyBhcmUgbm9uLWlnbm9yYWJsZS4gSWYgdGhlIHBhdHRlcm4gCiAqICAgICAgICAgICAiYSYjOTI7dTAzMDAiIGlzIHNlYXJjaGVkIGluIHRoZSB0YXJnZXQgdGV4dCAKICogICAgICAgICAgICJhJiM5Mjt1MDMyNSYjOTI7dTAzMDAiLCAKICogICAgICAgICAgIGEgbWF0Y2ggd2lsbCBiZSBmb3VuZCwgc2luY2UgdGhlIHRhcmdldCB0ZXh0IGlzIGNhbm9uaWNhbGx5IAogKiAgICAgICAgICAgZXF1aXZhbGVudCB0byAiYSYjOTI7dTAzMDAmIzkyO3UwMzI1IgogKiBvcHRpb24gMi4gUCBtYXRjaGVzIFMnIGFuZCBpZiBQIHN0YXJ0cyBvciBlbmRzIHdpdGggYSBjb21iaW5pbmcgbWFyaywgCiAqICAgICAgICAgICB0aGVyZSBleGlzdHMgbm8gbm9uLWlnbm9yYWJsZSBjb21iaW5pbmcgbWFyayBiZWZvcmUgb3IgYWZ0ZXIgU5IgCiAqICAgICAgICAgICBpbiBTIHJlc3BlY3RpdmVseS4gRm9sbG93aW5nIHRoZSBleGFtcGxlIGFib3ZlLCB0aGUgcGF0dGVybiAKICogICAgICAgICAgICJhJiM5Mjt1MDMwMCIgd2lsbCBub3QgZmluZCBhIG1hdGNoIGluICJhJiM5Mjt1MDMyNSYjOTI7dTAzMDAiLCAKICogICAgICAgICAgIHNpbmNlCiAqICAgICAgICAgICB0aGVyZSBleGlzdHMgYSBub24taWdub3JhYmxlIGFjY2VudCAnJiM5Mjt1MDMyNScgaW4gdGhlIG1pZGRsZSBvZiAKICogICAgICAgICAgICdhJyBhbmQgJyYjOTI7dTAzMDAnLiBFdmVuIHdpdGggYSB0YXJnZXQgdGV4dCBvZiAKICogICAgICAgICAgICJhJiM5Mjt1MDMwMCYjOTI7dTAzMjUiIGEgbWF0Y2ggd2lsbCBub3QgYmUgZm91bmQgYmVjYXVzZSBvZiB0aGUgCiAqICAgICAgICAgICBub24taWdub3JhYmxlIHRyYWlsaW5nIGFjY2VudCAmIzkyO3UwMzI1LgogKiA8L3ByZT4KICogT3B0aW9uIDIuIHdpbGwgYmUgdGhlIGRlZmF1bHQgbW9kZSBmb3IgZGVhbGluZyB3aXRoIGJvdW5kYXJ5IGFjY2VudHMgdW5sZXNzCiAqIHNwZWNpZmllZCB2aWEgdGhlIEFQSSBzZXRDYW5vbmljYWwoYm9vbGVhbikuCiAqIE9uZSByZXN0cmljdGlvbiBpcyB0byBiZSBub3RlZCBmb3Igb3B0aW9uIDEuIEN1cnJlbnRseSB0aGVyZSBhcmUgbm8gCiAqIGNvbXBvc2l0ZSBjaGFyYWN0ZXJzIHRoYXQgY29uc2lzdHMgb2YgYSBjaGFyYWN0ZXIgd2l0aCBjb21iaW5pbmcgY2xhc3MgPiAwIAogKiBiZWZvcmUgYSBjaGFyYWN0ZXIgd2l0aCBjb21iaW5pbmcgY2xhc3MgPT0gMC4gSG93ZXZlciwgaWYgc3VjaCBhIGNoYXJhY3RlciAKICogZXhpc3RzIGluIHRoZSBmdXR1cmUsIHRoZSBTdHJpbmdTZWFyY2ggbWF5IG5vdCB3b3JrIGNvcnJlY3RseSB3aXRoIG9wdGlvbiAxCiAqIHdoZW4gc3VjaCBjaGFyYWN0ZXJzIGFyZSBlbmNvdW50ZXJlZC4KICogPC9wPgogKiA8cD4KICogPHR0PlNlYXJjaEl0ZXJhdG9yPC90dD4gcHJvdmlkZXMgQVBJcyB0byBzcGVjaWZ5IHRoZSBzdGFydGluZyBwb3NpdGlvbiAKICogd2l0aGluIHRoZSB0ZXh0IHN0cmluZyB0byBiZSBzZWFyY2hlZCwgZS5nLiA8dHQ+c2V0SW5kZXg8L3R0PiwKICogPHR0PnByZWNlZGluZzwvdHQ+IGFuZCA8dHQ+Zm9sbG93aW5nPC90dD4uIFNpbmNlIHRoZSBzdGFydGluZyBwb3NpdGlvbiB3aWxsIAogKiBiZSBzZXQgYXMgaXQgaXMgc3BlY2lmaWVkLCBwbGVhc2UgdGFrZSBub3RlIHRoYXQgdGhlcmUgYXJlIHNvbWUgZGFuZ2Vyb3VzIAogKiBwb3NpdGlvbnMgd2hpY2ggdGhlIHNlYXJjaCBtYXkgcmVuZGVyIGluY29ycmVjdCByZXN1bHRzOgogKiA8dWw+CiAqIDxsaT4gVGhlIG1pZHN0IG9mIGEgc3Vic3RyaW5nIHRoYXQgcmVxdWlyZXMgZGVjb21wb3NpdGlvbi4KICogPGxpPiBJZiB0aGUgZm9sbG93aW5nIG1hdGNoIGlzIHRvIGJlIGZvdW5kLCB0aGUgcG9zaXRpb24gc2hvdWxkIG5vdCBiZSB0aGUKICogICAgICBzZWNvbmQgY2hhcmFjdGVyIHdoaWNoIHJlcXVpcmVzIHRvIGJlIHN3YXBwZWQgd2l0aCB0aGUgcHJlY2VkaW5nIAogKiAgICAgIGNoYXJhY3Rlci4gVmljZSB2ZXJzYSwgaWYgdGhlIHByZWNlZGluZyBtYXRjaCBpcyB0byBiZSBmb3VuZCwgCiAqICAgICAgcG9zaXRpb24gdG8gc2VhcmNoIGZyb20gc2hvdWxkIG5vdCBiZSB0aGUgZmlyc3QgY2hhcmFjdGVyIHdoaWNoIAogKiAgICAgIHJlcXVpcmVzIHRvIGJlIHN3YXBwZWQgd2l0aCB0aGUgbmV4dCBjaGFyYWN0ZXIuIEUuZyBjZXJ0YWluIFRoYWkgYW5kCiAqICAgICAgTGFvIGNoYXJhY3RlcnMgcmVxdWlyZSBzd2FwcGluZy4KICogPGxpPiBJZiBhIGZvbGxvd2luZyBwYXR0ZXJuIG1hdGNoIGlzIHRvIGJlIGZvdW5kLCBhbnkgcG9zaXRpb24gd2l0aGluIGEgCiAqICAgICAgY29udHJhY3Rpbmcgc2VxdWVuY2UgZXhjZXB0IHRoZSBmaXJzdCB3aWxsIGZhaWwuIFZpY2UgdmVyc2EgaWYgYSAKICogICAgICBwcmVjZWRpbmcgcGF0dGVybiBtYXRjaCBpcyB0byBiZSBmb3VuZCwgYSBpbnZhbGlkIHN0YXJ0aW5nIHBvaW50IAogKiAgICAgIHdvdWxkIGJlIGFueSBjaGFyYWN0ZXIgd2l0aGluIGEgY29udHJhY3Rpbmcgc2VxdWVuY2UgZXhjZXB0IHRoZSBsYXN0LgogKiA8L3VsPgogKiA8L3A+CiAqIDxwPgogKiBUaG91Z2ggY29sbGF0b3IgYXR0cmlidXRlcyB3aWxsIGJlIHRha2VuIGludG8gY29uc2lkZXJhdGlvbiB3aGlsZSAKICogcGVyZm9ybWluZyBtYXRjaGVzLCB0aGVyZSBhcmUgbm8gQVBJcyBwcm92aWRlZCBpbiBTdHJpbmdTZWFyY2ggZm9yIHNldHRpbmcgCiAqIGFuZCBnZXR0aW5nIHRoZSBhdHRyaWJ1dGVzLiBUaGVzZSBhdHRyaWJ1dGVzIGNhbiBiZSBzZXQgYnkgZ2V0dGluZyB0aGUgCiAqIGNvbGxhdG9yIGZyb20gPHR0PmdldENvbGxhdG9yPC90dD4gYW5kIHVzaW5nIHRoZSBBUElzIGluIAogKiA8dHQ+Y29tLmlibS5pY3UudGV4dC5Db2xsYXRvcjwvdHQ+LiBUbyB1cGRhdGUgU3RyaW5nU2VhcmNoIHRvIHRoZSBuZXcgCiAqIGNvbGxhdG9yIGF0dHJpYnV0ZXMsIDx0dD5yZXNldCgpPC90dD4gb3IgCiAqIDx0dD5zZXRDb2xsYXRvcihSdWxlQmFzZWRDb2xsYXRvcik8L3R0PiBoYXMgdG8gYmUgY2FsbGVkLgogKiA8L3A+CiAqIDxwPgogKiBDb25zdWx0IHRoZSAKICogPGEgaHJlZj1odHRwOi8vb3NzLnNvZnR3YXJlLmlibS5jb20vaWN1L3VzZXJndWlkZS9zZWFyY2hTdHJpbmcuaHRtbD4KICogU3RyaW5nIFNlYXJjaDwvYT4gdXNlciBndWlkZSBhbmQgdGhlIDxjb2RlPlNlYXJjaEl0ZXJhdG9yPC9jb2RlPiAKICogZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbiBhbmQgZXhhbXBsZXMgb2YgdXNlLgogKiA8L3A+CiAqIDxwPgogKiBUaGlzIGNsYXNzIGlzIG5vdCBzdWJjbGFzc2FibGUKICogPC9wPgogKiBAc2VlIFNlYXJjaEl0ZXJhdG9yCiAqIEBzZWUgUnVsZUJhc2VkQ29sbGF0b3IKICogQGF1dGhvciBMYXVyYSBXZXJuZXIsIHN5bndlZQogKiBAc3RhYmxlIElDVSAyLjAKICovCi8vIGludGVybmFsIG5vdGVzOiBhbGwgbWV0aG9kcyBkbyBub3QgZ3VhcmFudGVlIHRoZSBjb3JyZWN0IHN0YXR1cyBvZiB0aGUgCi8vIGNoYXJhY3Rlcml0ZXJhdG9yLiB0aGUgY2FsbGVyIGhhcyB0byBtYWludGFpbiB0aGUgb3JpZ2luYWwgaW5kZXggcG9zaXRpb24KLy8gaWYgbmVjZXNzYXJ5LiBtZXRob2RzIGNvdWxkIGNoYW5nZSB0aGUgaW5kZXggcG9zaXRpb24gYXMgaXQgZGVlbXMgZml0CnB1YmxpYyBmaW5hbCBjbGFzcyBTdHJpbmdTZWFyY2ggZXh0ZW5kcyBTZWFyY2hJdGVyYXRvcgp7CgkKCS8vIHB1YmxpYyBjb25zdHJ1Y3RvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCQogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyB0aGUgaXRlcmF0b3IgdG8gdXNlIHRoZSBsYW5ndWFnZS1zcGVjaWZpYyBydWxlcyBkZWZpbmVkIGluIAogICAgICogdGhlIGFyZ3VtZW50IGNvbGxhdG9yIHRvIHNlYXJjaCBmb3IgYXJndW1lbnQgcGF0dGVybiBpbiB0aGUgYXJndW1lbnQgCiAgICAgKiB0YXJnZXQgdGV4dC4gVGhlIGFyZ3VtZW50IGJyZWFraXRlciBpcyB1c2VkIHRvIGRlZmluZSBsb2dpY2FsIG1hdGNoZXMuCiAgICAgKiBTZWUgc3VwZXIgY2xhc3MgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBkZXRhaWxzIG9uIHRoZSB1c2Ugb2YgdGhlIHRhcmdldCAKICAgICAqIHRleHQgYW5kIEJyZWFrSXRlcmF0b3IuCiAgICAgKiBAcGFyYW0gcGF0dGVybiB0ZXh0IHRvIGxvb2sgZm9yLgogICAgICogQHBhcmFtIHRhcmdldCB0YXJnZXQgdGV4dCB0byBzZWFyY2ggZm9yIHBhdHRlcm4uIAogICAgICogQHBhcmFtIGNvbGxhdG9yIFJ1bGVCYXNlZENvbGxhdG9yIHRoYXQgZGVmaW5lcyB0aGUgbGFuZ3VhZ2UgcnVsZXMKICAgICAqIEBwYXJhbSBicmVha2VyIEEge0BsaW5rIEJyZWFrSXRlcmF0b3J9IHRoYXQgaXMgdXNlZCB0byBkZXRlcm1pbmUgdGhlIAogICAgICogICAgICAgICAgICAgICAgYm91bmRhcmllcyBvZiBhIGxvZ2ljYWwgbWF0Y2guIFRoaXMgYXJndW1lbnQgY2FuIGJlIG51bGwuCiAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB0aHJvd24gd2hlbiBhcmd1bWVudCB0YXJnZXQgaXMgbnVsbCwKICAgICAqICAgICAgICAgICAgb3Igb2YgbGVuZ3RoIDAKICAgICAqIEBzZWUgQnJlYWtJdGVyYXRvcgogICAgICogQHNlZSBSdWxlQmFzZWRDb2xsYXRvcgogICAgICogQHNlZSBTZWFyY2hJdGVyYXRvcgogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmdTZWFyY2goU3RyaW5nIHBhdHRlcm4sIENoYXJhY3Rlckl0ZXJhdG9yIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IgY29sbGF0b3IsIEJyZWFrSXRlcmF0b3IgYnJlYWtpdGVyKSAKICAgIHsKICAgICAgICBzdXBlcih0YXJnZXQsIGJyZWFraXRlcik7CiAgICAgICAgbV90ZXh0QmVnaW5PZmZzZXRfID0gdGFyZ2V0VGV4dC5nZXRCZWdpbkluZGV4KCk7CiAgICAgICAgbV90ZXh0TGltaXRPZmZzZXRfID0gdGFyZ2V0VGV4dC5nZXRFbmRJbmRleCgpOwogICAgICAgIG1fY29sbGF0b3JfID0gY29sbGF0b3I7CiAgICAgICAgbV9jb2xFSXRlcl8gPSBtX2NvbGxhdG9yXy5nZXRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IodGFyZ2V0KTsKICAgICAgICBtX3V0aWxDb2xFSXRlcl8gPSBjb2xsYXRvci5nZXRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoIiIpOwogICAgICAgIG1fY2VNYXNrXyA9IGdldE1hc2sobV9jb2xsYXRvcl8uZ2V0U3RyZW5ndGgoKSk7CiAgICAgICAgbV9pc0Nhbm9uaWNhbE1hdGNoXyA9IGZhbHNlOwogICAgICAgIG1fcGF0dGVybl8gPSBuZXcgUGF0dGVybihwYXR0ZXJuKTsKICAgICAgICBtX21hdGNoZWRJbmRleF8gPSBET05FOwogICAgICAgIAogICAgICAgIGluaXRpYWxpemUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEluaXRpYWxpemVzIHRoZSBpdGVyYXRvciB0byB1c2UgdGhlIGxhbmd1YWdlLXNwZWNpZmljIHJ1bGVzIGRlZmluZWQgaW4gCiAgICAgKiB0aGUgYXJndW1lbnQgY29sbGF0b3IgdG8gc2VhcmNoIGZvciBhcmd1bWVudCBwYXR0ZXJuIGluIHRoZSBhcmd1bWVudCAKICAgICAqIHRhcmdldCB0ZXh0LiBObyBCcmVha0l0ZXJhdG9ycyBhcmUgc2V0IHRvIHRlc3QgZm9yIGxvZ2ljYWwgbWF0Y2hlcy4KICAgICAqIEBwYXJhbSBwYXR0ZXJuIHRleHQgdG8gbG9vayBmb3IuCiAgICAgKiBAcGFyYW0gdGFyZ2V0IHRhcmdldCB0ZXh0IHRvIHNlYXJjaCBmb3IgcGF0dGVybi4gCiAgICAgKiBAcGFyYW0gY29sbGF0b3IgUnVsZUJhc2VkQ29sbGF0b3IgdGhhdCBkZWZpbmVzIHRoZSBsYW5ndWFnZSBydWxlcwogICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gdGhyb3duIHdoZW4gYXJndW1lbnQgdGFyZ2V0IGlzIG51bGwsCiAgICAgKiAgICAgICAgICAgIG9yIG9mIGxlbmd0aCAwCiAgICAgKiBAc2VlIFJ1bGVCYXNlZENvbGxhdG9yCiAgICAgKiBAc2VlIFNlYXJjaEl0ZXJhdG9yCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgcHVibGljIFN0cmluZ1NlYXJjaChTdHJpbmcgcGF0dGVybiwgQ2hhcmFjdGVySXRlcmF0b3IgdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvciBjb2xsYXRvcikgCiAgICB7CiAgICAgICAgdGhpcyhwYXR0ZXJuLCB0YXJnZXQsIGNvbGxhdG9yLCBCcmVha0l0ZXJhdG9yLmdldENoYXJhY3Rlckluc3RhbmNlKCkpOwogICAgfQoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgdGhlIGl0ZXJhdG9yIHRvIHVzZSB0aGUgbGFuZ3VhZ2Utc3BlY2lmaWMgcnVsZXMgYW5kIAogICAgICogYnJlYWsgaXRlcmF0b3IgcnVsZXMgZGVmaW5lZCBpbiB0aGUgYXJndW1lbnQgbG9jYWxlIHRvIHNlYXJjaCBmb3IgCiAgICAgKiBhcmd1bWVudCBwYXR0ZXJuIGluIHRoZSBhcmd1bWVudCB0YXJnZXQgdGV4dC4gCiAgICAgKiBTZWUgc3VwZXIgY2xhc3MgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBkZXRhaWxzIG9uIHRoZSB1c2Ugb2YgdGhlIHRhcmdldCAKICAgICAqIHRleHQgYW5kIEJyZWFrSXRlcmF0b3IuCiAgICAgKiBAcGFyYW0gcGF0dGVybiB0ZXh0IHRvIGxvb2sgZm9yLgogICAgICogQHBhcmFtIHRhcmdldCB0YXJnZXQgdGV4dCB0byBzZWFyY2ggZm9yIHBhdHRlcm4uIAogICAgICogQHBhcmFtIGxvY2FsZSBsb2NhbGUgdG8gdXNlIGZvciBsYW5ndWFnZSBhbmQgYnJlYWsgaXRlcmF0b3IgcnVsZXMKICAgICAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHRocm93biB3aGVuIGFyZ3VtZW50IHRhcmdldCBpcyBudWxsLAogICAgICogICAgICAgICAgICBvciBvZiBsZW5ndGggMC4gQ2xhc3NDYXN0RXhjZXB0aW9uIHRocm93biBpZiB0aGUgY29sbGF0b3IgZm9yIAogICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGxvY2FsZSBpcyBub3QgYSBSdWxlQmFzZWRDb2xsYXRvci4KICAgICAqIEBzZWUgQnJlYWtJdGVyYXRvcgogICAgICogQHNlZSBSdWxlQmFzZWRDb2xsYXRvcgogICAgICogQHNlZSBTZWFyY2hJdGVyYXRvcgogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmdTZWFyY2goU3RyaW5nIHBhdHRlcm4sIENoYXJhY3Rlckl0ZXJhdG9yIHRhcmdldCwgTG9jYWxlIGxvY2FsZSkKICAgIHsKICAgICAgICB0aGlzKHBhdHRlcm4sIHRhcmdldCwgKFJ1bGVCYXNlZENvbGxhdG9yKUNvbGxhdG9yLmdldEluc3RhbmNlKGxvY2FsZSksCiAgICAgICAgICAgICBCcmVha0l0ZXJhdG9yLmdldENoYXJhY3Rlckluc3RhbmNlKGxvY2FsZSkpOwogICAgfQoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgdGhlIGl0ZXJhdG9yIHRvIHVzZSB0aGUgbGFuZ3VhZ2Utc3BlY2lmaWMgcnVsZXMgYW5kIAogICAgICogYnJlYWsgaXRlcmF0b3IgcnVsZXMgZGVmaW5lZCBpbiB0aGUgZGVmYXVsdCBsb2NhbGUgdG8gc2VhcmNoIGZvciAKICAgICAqIGFyZ3VtZW50IHBhdHRlcm4gaW4gdGhlIGFyZ3VtZW50IHRhcmdldCB0ZXh0LiAKICAgICAqIFNlZSBzdXBlciBjbGFzcyBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGRldGFpbHMgb24gdGhlIHVzZSBvZiB0aGUgdGFyZ2V0IAogICAgICogdGV4dCBhbmQgQnJlYWtJdGVyYXRvci4KICAgICAqIEBwYXJhbSBwYXR0ZXJuIHRleHQgdG8gbG9vayBmb3IuCiAgICAgKiBAcGFyYW0gdGFyZ2V0IHRhcmdldCB0ZXh0IHRvIHNlYXJjaCBmb3IgcGF0dGVybi4gCiAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB0aHJvd24gd2hlbiBhcmd1bWVudCB0YXJnZXQgaXMgbnVsbCwKICAgICAqICAgICAgICAgICAgb3Igb2YgbGVuZ3RoIDAuIENsYXNzQ2FzdEV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIGNvbGxhdG9yIGZvciAKICAgICAqICAgICAgICAgICAgdGhlIGRlZmF1bHQgbG9jYWxlIGlzIG5vdCBhIFJ1bGVCYXNlZENvbGxhdG9yLgogICAgICogQHNlZSBCcmVha0l0ZXJhdG9yCiAgICAgKiBAc2VlIFJ1bGVCYXNlZENvbGxhdG9yCiAgICAgKiBAc2VlIFNlYXJjaEl0ZXJhdG9yCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgcHVibGljIFN0cmluZ1NlYXJjaChTdHJpbmcgcGF0dGVybiwgU3RyaW5nIHRhcmdldCkgCiAgICB7CiAgICAgICAgdGhpcyhwYXR0ZXJuLCBuZXcgU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3IodGFyZ2V0KSwKICAgICAgICAgICAgIChSdWxlQmFzZWRDb2xsYXRvcilDb2xsYXRvci5nZXRJbnN0YW5jZSgpLAogICAgICAgICAgICAgQnJlYWtJdGVyYXRvci5nZXRDaGFyYWN0ZXJJbnN0YW5jZSgpKTsKICAgIH0KCiAgICAvLyBwdWJsaWMgZ2V0dGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHN0cmVuZ3RoIHByb3BlcnR5IG9mIHRoZSBSdWxlQmFzZWRDb2xsYXRvciB1c2VkIGluIHNlYXJjaGluZy4gCiAgICAgKiBTZWUgdGhlIFJ1bGVCYXNlZENvbGxhdG9yIGNsYXNzIGRvY3VtZW50YXRpb24gZm9yIGEgZGVzY3JpcHRpb24gb2YgdGhlCiAgICAgKiBzdHJlbmd0aCBwcm9wZXJ0eS4KICAgICAqIEByZXR1cm4gdGhlIHN0cmVuZ3RoIHByb3BlcnR5IG9mIHRoZSBSdWxlQmFzZWRDb2xsYXRvciB1c2VkIGluIHNlYXJjaGluZwogICAgICogQHNlZSBSdWxlQmFzZWRDb2xsYXRvcgogICAgICogQHNlZSAjc2V0U3RyZW5ndGgKICAgICAqIEBzZWUgI2dldENvbGxhdG9yCiAgICAgKiBAb2Jzb2xldGUgSUNVIDIuMi4gVXNlIHRoaXMuZ2V0Q29sbGF0b3IoKS5nZXRTdHJlbmd0aCgpIGluc3RlYWQgc2luY2UgaXQKICAgICAqICAgICAgICAgICB3aWxsIGJlIHJlbW92ZWQgaW4gdGhhdCByZWxlYXNlLgogICAgICovCiAgICAvLy9DTE9WRVI6T0ZGCiAgICBwdWJsaWMgaW50IGdldFN0cmVuZ3RoKCkgewogICAgICAgIHJldHVybiBtX2NvbGxhdG9yXy5nZXRTdHJlbmd0aCgpOwogICAgfQogICAgLy8vQ0xPVkVSOk9OCiAgICAKICAgIC8qKgoJICogPHA+CiAgICAgKiBHZXRzIHRoZSBSdWxlQmFzZWRDb2xsYXRvciB1c2VkIGZvciB0aGUgbGFuZ3VhZ2UgcnVsZXMuCiAgICAgKiA8L3A+CgkgKiA8cD4KICAgICAqIFNpbmNlIFN0cmluZ1NlYXJjaCBkZXBlbmRzIG9uIHRoZSByZXR1cm5lZCBSdWxlQmFzZWRDb2xsYXRvciwgYW55IAoJICogY2hhbmdlcyB0byB0aGUgUnVsZUJhc2VkQ29sbGF0b3IgcmVzdWx0IHNob3VsZCBmb2xsb3cgd2l0aCBhIGNhbGwgdG8gCgkgKiBlaXRoZXIgU3RyaW5nU2VhcmNoLnJlc2V0KCkgb3IgCgkgKiBTdHJpbmdTZWFyY2guc2V0Q29sbGF0b3IoUnVsZUJhc2VkQ29sbGF0b3IpIHRvIGVuc3VyZSB0aGUgY29ycmVjdCAKCSAqIHNlYXJjaCBiZWhhdmlvdXIuCiAgICAgKiA8L3A+CgkgKiBAcmV0dXJuIFJ1bGVCYXNlZENvbGxhdG9yIHVzZWQgYnkgdGhpcyBTdHJpbmdTZWFyY2gKICAgICAqIEBzZWUgUnVsZUJhc2VkQ29sbGF0b3IKICAgICAqIEBzZWUgI3NldENvbGxhdG9yCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKCSAqLwogICAgcHVibGljIFJ1bGVCYXNlZENvbGxhdG9yIGdldENvbGxhdG9yKCkgCiAgICB7CiAgICAgICAgcmV0dXJuIG1fY29sbGF0b3JfOwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHBhdHRlcm4gZm9yIHdoaWNoIFN0cmluZ1NlYXJjaCBpcyBzZWFyY2hpbmcgZm9yLgogICAgICogQHJldHVybiB0aGUgcGF0dGVybiBzZWFyY2hlZCBmb3IKICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICBwdWJsaWMgU3RyaW5nIGdldFBhdHRlcm4oKSAKICAgIHsKICAgICAgICByZXR1cm4gbV9wYXR0ZXJuXy50YXJnZXRUZXh0OwogICAgfQogICAgCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgaW5kZXggaW4gdGhlIHRhcmdldCB0ZXh0IHdoZXJlIHRoZSBpdGVyYXRvciBpcyBjdXJyZW50bHkgCiAgICAgKiBwb3NpdGlvbmVkIGF0LiAKICAgICAqIElmIHRoZSBpdGVyYXRpb24gaGFzIGdvbmUgcGFzdCB0aGUgZW5kIG9mIHRoZSB0YXJnZXQgdGV4dCBvciBwYXN0IAogICAgICogdGhlIGJlZ2lubmluZyBmb3IgYSBiYWNrd2FyZHMgc2VhcmNoLCB7QGxpbmsgI0RPTkV9IGlzIHJldHVybmVkLgogICAgICogQHJldHVybiBpbmRleCBpbiB0aGUgdGFyZ2V0IHRleHQgd2hlcmUgdGhlIGl0ZXJhdG9yIGlzIGN1cnJlbnRseSAKICAgICAqICAgICAgICAgcG9zaXRpb25lZCBhdAogICAgICogQGRyYWZ0IElDVSAyLjIKICAgICAqLwogICAgcHVibGljIGludCBnZXRJbmRleCgpIAogICAgewogICAgICAgIGludCByZXN1bHQgPSBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKTsKICAgICAgICBpZiAoaXNPdXRPZkJvdW5kcyhtX3RleHRCZWdpbk9mZnNldF8sIG1fdGV4dExpbWl0T2Zmc2V0XywgcmVzdWx0KSkgewogICAgICAgICAgICByZXR1cm4gRE9ORTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgY2Fub25pY2FsIG1hdGNoZXMgKG9wdGlvbiAxLCBhcyBkZXNjcmliZWQgaW4gdGhlIAogICAgICogY2xhc3MgZG9jdW1lbnRhdGlvbikgaXMgc2V0LgogICAgICogU2VlIHNldENhbm9uaWNhbChib29sZWFuKSBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KICAgICAqIEBzZWUgI3NldENhbm9uaWNhbAogICAgICogQHJldHVybiB0cnVlIGlmIGNhbm9uaWNhbCBtYXRjaGVzIGlzIHNldCwgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKiBAZHJhZnQgSUNVIDIuMgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc0Nhbm9uaWNhbCgpIAogICAgewogICAgICAgIHJldHVybiBtX2lzQ2Fub25pY2FsTWF0Y2hfOwogICAgfQogICAgCiAgICAvLyBwdWJsaWMgc2V0dGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgCiAgICAvKioKICAgICAqIDxwPgogICAgICogU2V0cyB0aGUgc3RyZW5ndGggcHJvcGVydHkgb2YgdGhlIFJ1bGVCYXNlZENvbGxhdG9yIHVzZWQgZm9yIHNlYXJjaGluZy4KICAgICAqIFNlZSB0aGUgQ29sbGF0b3IgZG9jdW1lbnRhdGlvbiBmb3IgYSBkZXNjcmlwdGlvbiBvZiB0aGUgc3RyZW5ndGhzLgogICAgICogPC9wPgogICAgICogQG9ic29sZXRlIElDVSAyLjIuIFVzZSB0aGlzLmdldENvbGxhdG9yKCkuc2V0U3RyZW5ndGgoaW50KSBpbnN0ZWFkIHNpbmNlCiAgICAgKiAgICAgICAgICAgaXQgd2lsbCBiZSByZW1vdmVkIGluIHRoYXQgcmVsZWFzZS4KICAgICAqICAgICAgICAgICAgIEFmdGVyIHdoaWNoIFN0cmluZ1NlYXJjaC5yZXNldCgpIAogICAgICogICAgICAgICAgICAgb3IgU3RyaW5nU2VhcmNoLnNldENvbGxhdG9yKHRoaXMuZ2V0Q29sbGF0b3IoKSkgc2hvdWxkIGJlCiAgICAgKiAgICAgICAgICAgICBjYWxsZWQgdG8gdXBkYXRlIFN0cmluZ1NlYXJjaC5dCiAgICAgKiBAc2VlIENvbGxhdG9yCiAgICAgKiBAc2VlIENvbGxhdG9yI1BSSU1BUlkKICAgICAqIEBzZWUgQ29sbGF0b3IjU0VDT05EQVJZCiAgICAgKiBAc2VlIENvbGxhdG9yI1RFUlRJQVJZCiAgICAgKiBAc2VlIENvbGxhdG9yI1FVQVRFUk5BUlkKICAgICAqIEBzZWUgQ29sbGF0b3IjSURFTlRJQ0FMCiAgICAgKiBAc2VlICNzZXRDb2xsYXRvcgogICAgICogQHNlZSAjZ2V0Q29sbGF0b3IKICAgICAqLwogICAgLy8vQ0xPVkVSOk9GRgogICAgcHVibGljIHZvaWQgc2V0U3RyZW5ndGgoaW50IG5ld1N0cmVuZ3RoKSAKICAgIHsKICAgICAgICAvLyBEdWUgdG8gYSBidWcgKD8pIGluIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciwgd2UgbXVzdCBzZXQgdGhlCiAgICAgICAgLy8gY29sbGF0b3IncyBzdHJlbmd0aCBhcyB3ZWxsLCBzaW5jZSB0aGUgaXRlcmF0b3IgaXMgZ29pbmcgdG8KICAgICAgICAvLyBtYXNrIG91dCB0aGUgcG9ydGlvbnMgb2YgdGhlIGNvbGxhdGlvbiBlbGVtZW50IHRoYXQgYXJlIG5vdAogICAgICAgIC8vIHJlbGV2YW50IGZvciB0aGUgY29sbGF0b3IncyBjdXJyZW50IHN0cmVuZ3RoIHNldHRpbmcKICAgICAgICAvLyBOb3RlIHRoYXQgdGhpcyBtYWtlcyBpdCBpbXBvc3NpYmxlIHRvIHNoYXJlIGEgQ29sbGF0b3IgYW1vbmcKICAgICAgICAvLyBtdWx0aXBsZSBTdHJpbmdTZWFyY2ggb2JqZWN0cyBpZiB5b3UgYWRqdXN0IFN0cmVuZ3RoIHNldHRpbmdzLgogICAgICAgIG1fY29sbGF0b3JfLnNldFN0cmVuZ3RoKG5ld1N0cmVuZ3RoKTsKICAgICAgICBpbml0aWFsaXplKCk7CiAgICB9CiAgICAvLy9DTE9WRVI6T04KICAgIAogICAgLyoqCiAgICAgKiA8cD4KICAgICAqIFNldHMgdGhlIFJ1bGVCYXNlZENvbGxhdG9yIHRvIGJlIHVzZWQgZm9yIGxhbmd1YWdlLXNwZWNpZmljIHNlYXJjaGluZy4KICAgICAqIDwvcD4KICAgICAqIDxwPgogICAgICogVGhpcyBtZXRob2QgY2F1c2VzIGludGVybmFsIGRhdGEgc3VjaCBhcyBCb3llci1Nb29yZSBzaGlmdCB0YWJsZXMKICAgICAqIHRvIGJlIHJlY2FsY3VsYXRlZCwgYnV0IHRoZSBpdGVyYXRvcidzIHBvc2l0aW9uIGlzIHVuY2hhbmdlZC4KICAgICAqIDwvcD4KICAgICAqIEBwYXJhbSBjb2xsYXRvciB0byB1c2UgZm9yIHRoaXMgU3RyaW5nU2VhcmNoCiAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB0aHJvd24gd2hlbiBjb2xsYXRvciBpcyBudWxsCiAgICAgKiBAc2VlICNnZXRDb2xsYXRvcgogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldENvbGxhdG9yKFJ1bGVCYXNlZENvbGxhdG9yIGNvbGxhdG9yKSAKICAgIHsKICAgIAlpZiAoY29sbGF0b3IgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJDb2xsYXRvciBjYW4gbm90IGJlIG51bGwiKTsKICAgICAgICB9CiAgICAgICAgbV9jb2xsYXRvcl8gPSBjb2xsYXRvcjsKICAgICAgICBtX2NlTWFza18gPSBnZXRNYXNrKG1fY29sbGF0b3JfLmdldFN0cmVuZ3RoKCkpOwogICAgICAgIC8vIGlmIHN0YXR1cyBpcyBhIGZhaWx1cmUsIHVjb2xfZ2V0QXR0cmlidXRlIHJldHVybnMgVUNPTF9ERUZBVUxUCiAgICAgICAgaW5pdGlhbGl6ZSgpOwogICAgICAgIG1fY29sRUl0ZXJfLnNldENvbGxhdG9yKG1fY29sbGF0b3JfKTsKICAgICAgICBtX3V0aWxDb2xFSXRlcl8uc2V0Q29sbGF0b3IobV9jb2xsYXRvcl8pOwogICAgfQogICAgCiAgICAvKioKICAgICAqIDxwPgogICAgICogU2V0IHRoZSBwYXR0ZXJuIHRvIHNlYXJjaCBmb3IuICAKICAgICAqIDwvcD4KICAgICAqIDxwPgogICAgICogVGhpcyBtZXRob2QgY2F1c2VzIGludGVybmFsIGRhdGEgc3VjaCBhcyBCb3llci1Nb29yZSBzaGlmdCB0YWJsZXMKICAgICAqIHRvIGJlIHJlY2FsY3VsYXRlZCwgYnV0IHRoZSBpdGVyYXRvcidzIHBvc2l0aW9uIGlzIHVuY2hhbmdlZC4KICAgICAqIDwvcD4KICAgICAqIEBwYXJhbSBwYXR0ZXJuIGZvciBzZWFyY2hpbmcKICAgICAqIEBzZWUgI2dldFBhdHRlcm4KICAgICAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHRocm93biBpZiBwYXR0ZXJuIGlzIG51bGwgb3Igb2YKICAgICAqIAkJCSAgbGVuZ3RoIDAKICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRQYXR0ZXJuKFN0cmluZyBwYXR0ZXJuKSAKICAgIHsKICAgIAlpZiAocGF0dGVybiA9PSBudWxsIHx8IHBhdHRlcm4ubGVuZ3RoKCkgPD0gMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAJCSJQYXR0ZXJuIHRvIHNlYXJjaCBmb3IgY2FuIG5vdCBiZSBudWxsIG9yIG9mIGxlbmd0aCAwIik7CiAgICAgICAgfQogICAgICAgIG1fcGF0dGVybl8udGFyZ2V0VGV4dCA9IHBhdHRlcm47CiAgICAgICAgaW5pdGlhbGl6ZSgpOwogICAgfQogICAgCiAgICAvKioKIAkgKiBTZXQgdGhlIHRhcmdldCB0ZXh0IHRvIGJlIHNlYXJjaGVkLiBUZXh0IGl0ZXJhdGlvbiB3aWxsIGhlbmNlIGJlZ2luIGF0IAogICAgICogdGhlIHN0YXJ0IG9mIHRoZSB0ZXh0IHN0cmluZy4gVGhpcyBtZXRob2QgaXMgdXNlZnVsIGlmIHlvdSB3YW50IHRvIAogICAgICogcmUtdXNlIGFuIGl0ZXJhdG9yIHRvIHNlYXJjaCB3aXRoaW4gYSBkaWZmZXJlbnQgYm9keSBvZiB0ZXh0LgogICAgICogQHBhcmFtIHRleHQgbmV3IHRleHQgaXRlcmF0b3IgdG8gbG9vayBmb3IgbWF0Y2gsIAogICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gdGhyb3duIHdoZW4gdGV4dCBpcyBudWxsIG9yIGhhcwogICAgICogICAgICAgICAgICAwIGxlbmd0aAogICAgICogQHNlZSAjZ2V0VGFyZ2V0CgkgKiBAZHJhZnQgSUNVIDIuMgoJICovCglwdWJsaWMgdm9pZCBzZXRUYXJnZXQoQ2hhcmFjdGVySXRlcmF0b3IgdGV4dCkKCXsKCQlzdXBlci5zZXRUYXJnZXQodGV4dCk7CiAgICAgICAgbV90ZXh0QmVnaW5PZmZzZXRfID0gdGFyZ2V0VGV4dC5nZXRCZWdpbkluZGV4KCk7CiAgICAgICAgbV90ZXh0TGltaXRPZmZzZXRfID0gdGFyZ2V0VGV4dC5nZXRFbmRJbmRleCgpOwogICAgICAgIG1fY29sRUl0ZXJfLnNldFRleHQodGFyZ2V0VGV4dCk7Cgl9CiAgICAKICAgIC8qKgoJICogPHA+CiAgICAgKiBTZXRzIHRoZSBwb3NpdGlvbiBpbiB0aGUgdGFyZ2V0IHRleHQgd2hpY2ggdGhlIG5leHQgc2VhcmNoIHdpbGwgc3RhcnQgCiAgICAgKiBmcm9tIHRvIHRoZSBhcmd1bWVudC4gVGhpcyBtZXRob2QgY2xlYXJzIGFsbCBwcmV2aW91cyBzdGF0ZXMuCiAgICAgKiA8L3A+CiAgICAgKiA8cD4KICAgICAqIFRoaXMgbWV0aG9kIHRha2VzIHRoZSBhcmd1bWVudCBwb3NpdGlvbiBhbmQgc2V0cyB0aGUgcG9zaXRpb24gaW4gdGhlIAogICAgICogdGFyZ2V0IHRleHQgYWNjb3JkaW5nbHksIHdpdGhvdXQgY2hlY2tpbmcgaWYgcG9zaXRpb24gaXMgcG9pbnRpbmcgdG8gYSAKICAgICAqIHZhbGlkIHN0YXJ0aW5nIHBvaW50IHRvIGJlZ2luIHNlYXJjaGluZy4KICAgICAqIDwvcD4KICAgICAqIDxwPgogICAgICogU2VhcmNoIHBvc2l0aW9ucyB0aGF0IG1heSByZW5kZXIgaW5jb3JyZWN0IHJlc3VsdHMgYXJlIGhpZ2hsaWdodGVkIGluIAogICAgICogdGhlIGNsYXNzIGRvY3VtZW50YXRpb24uCiAgICAgKiA8L3A+CiAgICAgKiBAcGFyYW0gcG9zaXRpb24gaW5kZXggdG8gc3RhcnQgbmV4dCBzZWFyY2ggZnJvbS4KICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB0aHJvd24gaWYgYXJndW1lbnQgcG9zaXRpb24gaXMgb3V0CiAgICAgKiAgICAgICAgICAgIG9mIHRoZSB0YXJnZXQgdGV4dCByYW5nZS4KICAgICAqIEBzZWUgI2dldEluZGV4CiAgICAgKiBAZHJhZnQgSUNVIDIuMgoJICovCglwdWJsaWMgdm9pZCBzZXRJbmRleChpbnQgcG9zaXRpb24pCgl7CgkJc3VwZXIuc2V0SW5kZXgocG9zaXRpb24pOwogICAgICAgIG1fbWF0Y2hlZEluZGV4XyA9IERPTkU7CiAgICAgICAgbV9jb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQocG9zaXRpb24pOwoJfQoJCgkvKioKCSAqIDxwPgogICAgICogU2V0IHRoZSBjYW5vbmljYWwgbWF0Y2ggbW9kZS4gU2VlIGNsYXNzIGRvY3VtZW50YXRpb24gZm9yIGRldGFpbHMuCiAgICAgKiBUaGUgZGVmYXVsdCBzZXR0aW5nIGZvciB0aGlzIHByb3BlcnR5IGlzIGZhbHNlLgogICAgICogPC9wPgoJICogQHBhcmFtIGFsbG93Q2Fub25pY2FsIGZsYWcgaW5kaWNhdG9yIGlmIGNhbm9uaWNhbCBtYXRjaGVzIGFyZSBhbGxvd2VkCiAgICAgKiBAc2VlICNpc0Nhbm9uaWNhbAoJICogQGRyYWZ0IElDVSAyLjIKCSAqLwoJcHVibGljIHZvaWQgc2V0Q2Fub25pY2FsKGJvb2xlYW4gYWxsb3dDYW5vbmljYWwpCgl7CgkJbV9pc0Nhbm9uaWNhbE1hdGNoXyA9IGFsbG93Q2Fub25pY2FsOwoJCWlmIChtX2lzQ2Fub25pY2FsTWF0Y2hfID09IHRydWUpIHsKCQkJaWYgKG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18gPT0gbnVsbCkgewoJCQkJbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXyA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKCQkJfQoJCQllbHNlIHsKCQkJCW1fY2Fub25pY2FsUHJlZml4QWNjZW50c18uZGVsZXRlKDAsIAoJCQkJCQkJCQkJCW1fY2Fub25pY2FsUHJlZml4QWNjZW50c18ubGVuZ3RoKCkpOwoJCQl9CgkJCWlmIChtX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfID09IG51bGwpIHsKCQkJCW1fY2Fub25pY2FsU3VmZml4QWNjZW50c18gPSBuZXcgU3RyaW5nQnVmZmVyKCk7CgkJCX0KCQkJZWxzZSB7CgkJCQltX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfLmRlbGV0ZSgwLCAKCQkJCQkJCQkJCQltX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfLmxlbmd0aCgpKTsKCQkJfQoJCX0KCX0KCQoJLy8gcHVibGljIG1pc2NlbGxhbmVvdXMgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJCgkvKiogCgkgKiA8cD4KICAgICAqIFJlc2V0cyB0aGUgc2VhcmNoIGl0ZXJhdGlvbi4gQWxsIHByb3BlcnRpZXMgd2lsbCBiZSByZXNldCB0byB0aGUgCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICogPC9wPgogICAgICogPHA+CiAgICAgKiBTZWFyY2ggd2lsbCBiZWdpbiBhdCB0aGUgc3RhcnQgb2YgdGhlIHRhcmdldCB0ZXh0IGlmIGEgZm9yd2FyZCBpdGVyYXRpb24gCiAgICAgKiBpcyBpbml0aWF0ZWQgYmVmb3JlIGEgYmFja3dhcmRzIGl0ZXJhdGlvbi4gT3RoZXJ3aXNlIGlmIGEgCiAgICAgKiBiYWNrd2FyZHMgaXRlcmF0aW9uIGlzIGluaXRpYXRlZCBiZWZvcmUgYSBmb3J3YXJkcyBpdGVyYXRpb24sIHRoZSBzZWFyY2ggCiAgICAgKiB3aWxsIGJlZ2luIGF0IHRoZSBlbmQgb2YgdGhlIHRhcmdldCB0ZXh0LgogICAgICogPC9wPgogICAgICogPHA+CiAgICAgKiBDYW5vbmljYWwgbWF0Y2ggb3B0aW9uIHdpbGwgYmUgcmVzZXQgdG8gZmFsc2UsIGllIGFuIGV4YWN0IG1hdGNoLgogICAgICogPC9wPgoJICogQGRyYWZ0IElDVSAyLjIKCSAqLwoJcHVibGljIHZvaWQgcmVzZXQoKQoJewoJCS8vIHJlc2V0IGlzIHNldHRpbmcgdGhlIGF0dHJpYnV0ZXMgdGhhdCBhcmUgYWxyZWFkeSBpbiBzdHJpbmcgc2VhcmNoLCAKCQkvLyBoZW5jZSBhbGwgYXR0cmlidXRlcyBpbiB0aGUgY29sbGF0b3Igc2hvdWxkIGJlIHJldHJpZXZlZCB3aXRob3V0IGFueSAKCQkvLyBwcm9ibGVtcwoJCXN1cGVyLnJlc2V0KCk7CiAgICAgICAgbV9pc0Nhbm9uaWNhbE1hdGNoXyA9IGZhbHNlOwogICAgICAgIG1fY2VNYXNrXyA9IGdldE1hc2sobV9jb2xsYXRvcl8uZ2V0U3RyZW5ndGgoKSk7CiAgICAgICAgLy8gaWYgc3RhdHVzIGlzIGEgZmFpbHVyZSwgdWNvbF9nZXRBdHRyaWJ1dGUgcmV0dXJucyBVQ09MX0RFRkFVTFQKICAgICAgICBpbml0aWFsaXplKCk7CiAgICAgICAgbV9jb2xFSXRlcl8uc2V0Q29sbGF0b3IobV9jb2xsYXRvcl8pOwogICAgICAgIG1fY29sRUl0ZXJfLnJlc2V0KCk7CiAgICAgICAgbV91dGlsQ29sRUl0ZXJfLnNldENvbGxhdG9yKG1fY29sbGF0b3JfKTsKCX0KCiAgICAvLyBwcm90ZWN0ZWQgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgCiAgICAvKioKICAgICAqIDxwPgogICAgICogQ29uY3JldGUgbWV0aG9kIHRvIHByb3ZpZGUgdGhlIG1lY2hhbmlzbSAKICAgICAqIGZvciBmaW5kaW5nIHRoZSBuZXh0IDxiPmZvcndhcmRzPC9iPiBtYXRjaCBpbiB0aGUgdGFyZ2V0IHRleHQuCiAgICAgKiBTZWUgc3VwZXIgY2xhc3MgZG9jdW1lbnRhdGlvbiBmb3IgaXRzIHVzZS4KICAgICAqIDwvcD4gIAogICAgICogQHBhcmFtIHN0YXJ0IGluZGV4IGluIHRoZSB0YXJnZXQgdGV4dCBhdCB3aGljaCB0aGUgZm9yd2FyZHMgc2VhcmNoIAogICAgICogICAgICAgIHNob3VsZCBiZWdpbi4KICAgICAqIEByZXR1cm4gdGhlIHN0YXJ0aW5nIGluZGV4IG9mIHRoZSBuZXh0IGZvcndhcmRzIG1hdGNoIGlmIGZvdW5kLCBET05FIAogICAgICogICAgICAgICBvdGhlcndpc2UKICAgICAqIEBzZWUgI2hhbmRsZVByZXZpb3VzKGludCkKICAgICAqIEBzZWUgI0RPTkUKICAgICAqIEBkcmFmdCBJQ1UgMi4yCiAgICAgKi8KICAgIHByb3RlY3RlZCBpbnQgaGFuZGxlTmV4dChpbnQgc3RhcnQpCiAgICB7CiAgICAJaWYgKG1fcGF0dGVybl8ubV9DRUxlbmd0aF8gPT0gMCkgewogICAgICAgICAgICBtYXRjaExlbmd0aCA9IDA7CiAgICAgICAgICAgIGlmIChtX21hdGNoZWRJbmRleF8gPT0gRE9ORSAmJiBzdGFydCA9PSBtX3RleHRCZWdpbk9mZnNldF8pIHsKICAgICAgICAgICAgICAgIG1fbWF0Y2hlZEluZGV4XyA9IHN0YXJ0OwogICAgICAgICAgICAgICAgcmV0dXJuIG1fbWF0Y2hlZEluZGV4XzsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgIAkJdGFyZ2V0VGV4dC5zZXRJbmRleChzdGFydCk7CgkgICAgICAgIGNoYXIgY2ggPSB0YXJnZXRUZXh0LmN1cnJlbnQoKTsKCSAgICAgICAgLy8gY2ggY2FuIG5ldmVyIGJlIGRvbmUsIGl0IGlzIGhhbmRsZWQgYnkgbmV4dCgpCgkgICAgICAgIGNoYXIgY2gyID0gdGFyZ2V0VGV4dC5uZXh0KCk7CgkgICAgICAgIGlmIChjaDIgPT0gQ2hhcmFjdGVySXRlcmF0b3IuRE9ORSkgewoJICAgICAgICAgICAgbV9tYXRjaGVkSW5kZXhfID0gRE9ORTsJCgkgICAgICAgIH0KCSAgICAgICAgZWxzZSB7CgkgICAgICAgICAgICBtX21hdGNoZWRJbmRleF8gPSB0YXJnZXRUZXh0LmdldEluZGV4KCk7CgkgICAgICAgIH0KCSAgICAgICAgaWYgKFVURjE2LmlzTGVhZFN1cnJvZ2F0ZShjaCkgJiYgVVRGMTYuaXNUcmFpbFN1cnJvZ2F0ZShjaDIpKSB7CgkgICAgICAgICAgICB0YXJnZXRUZXh0Lm5leHQoKTsKCSAgICAgICAgICAgIG1fbWF0Y2hlZEluZGV4XyA9IHRhcmdldFRleHQuZ2V0SW5kZXgoKTsKCSAgICAgICAgfQoJICAgIH0KCSAgICBlbHNlIHsKCSAgICAJaWYgKG1hdGNoTGVuZ3RoIDw9IDApIHsKICAgICAgICAgICAgICAgIC8vIHdlIG11c3QgaGF2ZSByZXZlcnNlZCBkaXJlY3Rpb24gYWZ0ZXIgd2UgcmVhY2hlZCB0aGUgc3RhcnQKICAgICAgICAgICAgICAgIC8vIG9mIHRoZSB0YXJnZXQgdGV4dAogICAgICAgICAgICAgICAgLy8gc2VlIFNlYXJjaEl0ZXJhdG9yIG5leHQoKSwgaXQgY2hlY2tzIHRoZSBib3VuZHMgYW5kIHJldHVybnMKICAgICAgICAgICAgICAgIC8vIGlmIGl0IGV4Y2VlZHMgdGhlIHJhbmdlLiBJdCBkb2VzIG5vdCBhbGxvdyBzZXR0aW5nIG9mCiAgICAgICAgICAgICAgICAvLyBtX21hdGNoZWRJbmRleAogICAgICAgICAgICAgICAgbV9tYXRjaGVkSW5kZXhfID0gRE9ORTsKICAgICAgICAgICAgfQogICAgCgkgICAgICAgIC8vIHN0YXR1cyBjaGVja2VkIGJlbG93CgkgICAgICAgIGlmIChtX2lzQ2Fub25pY2FsTWF0Y2hfKSB7CgkgICAgICAgICAgICAvLyBjYW4ndCB1c2UgZXhhY3QgaGVyZSBzaW5jZSBleHRyYSBhY2NlbnRzIGFyZSBhbGxvd2VkLgoJICAgICAgICAgICAgaGFuZGxlTmV4dENhbm9uaWNhbChzdGFydCk7CgkgICAgICAgIH0KCSAgICAgICAgZWxzZSB7CgkgICAgICAgICAgICBoYW5kbGVOZXh0RXhhY3Qoc3RhcnQpOwoJICAgICAgICB9CgkgICAgfQogICAgICAgIGlmIChtX21hdGNoZWRJbmRleF8gPT0gRE9ORSkgewogICAgICAgICAgICB0YXJnZXRUZXh0LnNldEluZGV4KG1fdGV4dExpbWl0T2Zmc2V0Xyk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICB0YXJnZXRUZXh0LnNldEluZGV4KG1fbWF0Y2hlZEluZGV4Xyk7CiAgICAgICAgfQogICAgCXJldHVybiBtX21hdGNoZWRJbmRleF87CiAgICB9CiAgICAKICAgIC8qKgoJICogPHA+CiAgICAgKiBDb25jcmV0ZSBtZXRob2QgdG8gcHJvdmlkZSB0aGUgbWVjaGFuaXNtIAogICAgICogZm9yIGZpbmRpbmcgdGhlIG5leHQgPGI+YmFja3dhcmRzPC9iPiBtYXRjaCBpbiB0aGUgdGFyZ2V0IHRleHQuCiAgICAgKiBTZWUgc3VwZXIgY2xhc3MgZG9jdW1lbnRhdGlvbiBmb3IgaXRzIHVzZS4KICAgICAqIDwvcD4gIAogICAgICogQHBhcmFtIHN0YXJ0IGluZGV4IGluIHRoZSB0YXJnZXQgdGV4dCBhdCB3aGljaCB0aGUgYmFja3dhcmRzIHNlYXJjaCAKICAgICAqICAgICAgICBzaG91bGQgYmVnaW4uCiAgICAgKiBAcmV0dXJuIHRoZSBzdGFydGluZyBpbmRleCBvZiB0aGUgbmV4dCBiYWNrd2FyZHMgbWF0Y2ggaWYgZm91bmQsIERPTkUgCiAgICAgKiAgICAgICAgIG90aGVyd2lzZQogICAgICogQHNlZSAjaGFuZGxlTmV4dChpbnQpCiAgICAgKiBAc2VlICNET05FCiAgICAgKiBAZHJhZnQgSUNVIDIuMgoJICovCiAgICBwcm90ZWN0ZWQgaW50IGhhbmRsZVByZXZpb3VzKGludCBzdGFydCkKICAgIHsKICAgIAlpZiAobV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyA9PSAwKSB7CiAgICAgICAgICAgIG1hdGNoTGVuZ3RoID0gMDsKCSAgICAgICAgLy8gc3RhcnQgY2FuIG5ldmVyIGJlIERPTkUgb3IgMCwgaXQgaXMgaGFuZGxlZCBpbiBwcmV2aW91cwogICAgICAgICAgICB0YXJnZXRUZXh0LnNldEluZGV4KHN0YXJ0KTsKICAgICAgICAgICAgY2hhciBjaCA9IHRhcmdldFRleHQucHJldmlvdXMoKTsKICAgICAgICAgICAgaWYgKGNoID09IENoYXJhY3Rlckl0ZXJhdG9yLkRPTkUpIHsKICAgICAgICAgICAgCW1fbWF0Y2hlZEluZGV4XyA9IERPTkU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIAltX21hdGNoZWRJbmRleF8gPSB0YXJnZXRUZXh0LmdldEluZGV4KCk7CgkgICAgICAgICAgICBpZiAoVVRGMTYuaXNUcmFpbFN1cnJvZ2F0ZShjaCkpIHsKCSAgICAgICAgICAgIAlpZiAoVVRGMTYuaXNMZWFkU3Vycm9nYXRlKHRhcmdldFRleHQucHJldmlvdXMoKSkpIHsKCSAgICAgICAgICAgICAgICAgICAgbV9tYXRjaGVkSW5kZXhfID0gdGFyZ2V0VGV4dC5nZXRJbmRleCgpOwoJICAgICAgICAgICAgCX0KCSAgICAgICAgICAgIH0KICAgICAgICAgICAgfSAgICAgICAgICAgIAogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgaWYgKG1hdGNoTGVuZ3RoID09IDApIHsKICAgICAgICAgICAgICAgIC8vIHdlIG11c3QgaGF2ZSByZXZlcnNlZCBkaXJlY3Rpb24gYWZ0ZXIgd2UgcmVhY2hlZCB0aGUgZW5kCiAgICAgICAgICAgICAgICAvLyBvZiB0aGUgdGFyZ2V0IHRleHQKICAgICAgICAgICAgICAgIC8vIHNlZSBTZWFyY2hJdGVyYXRvciBuZXh0KCksIGl0IGNoZWNrcyB0aGUgYm91bmRzIGFuZCByZXR1cm5zCiAgICAgICAgICAgICAgICAvLyBpZiBpdCBleGNlZWRzIHRoZSByYW5nZS4gSXQgZG9lcyBub3QgYWxsb3cgc2V0dGluZyBvZgogICAgICAgICAgICAgICAgLy8gbV9tYXRjaGVkSW5kZXgKICAgICAgICAgICAgICAgIG1fbWF0Y2hlZEluZGV4XyA9IERPTkU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG1faXNDYW5vbmljYWxNYXRjaF8pIHsKICAgICAgICAgICAgICAgIC8vIGNhbid0IHVzZSBleGFjdCBoZXJlIHNpbmNlIGV4dHJhIGFjY2VudHMgYXJlIGFsbG93ZWQuCiAgICAgICAgICAgICAgICBoYW5kbGVQcmV2aW91c0Nhbm9uaWNhbChzdGFydCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBoYW5kbGVQcmV2aW91c0V4YWN0KHN0YXJ0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKG1fbWF0Y2hlZEluZGV4XyA9PSBET05FKSB7CiAgICAgICAgICAgIHRhcmdldFRleHQuc2V0SW5kZXgobV90ZXh0QmVnaW5PZmZzZXRfKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIHRhcmdldFRleHQuc2V0SW5kZXgobV9tYXRjaGVkSW5kZXhfKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1fbWF0Y2hlZEluZGV4XzsKICAgIH0KCiAgICAvLyBwcml2YXRlIHN0YXRpYyBpbm5lciBjbGFzc2VzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIAogICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgUGF0dGVybiAKICAgIHsKICAgIAkvLyBwcm90ZWN0ZWQgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgCQogICAgCS8qKgogICAgCSAqIFBhdHRlcm4gc3RyaW5nCiAgICAJICovCiAgICAJcHJvdGVjdGVkIFN0cmluZyB0YXJnZXRUZXh0OwogICAgICAgIC8qKgogICAgICAgICAqIEFycmF5IGNvbnRhaW5pbmcgdGhlIGNvbGxhdGlvbiBlbGVtZW50cyBvZiB0YXJnZXRUZXh0CiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIGludCBtX0NFX1tdOwogICAgICAgIC8qKgogICAgICAgICAqIE51bWJlciBvZiBjb2xsYXRpb24gZWxlbWVudHMgaW4gbV9DRV8KICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgaW50IG1fQ0VMZW5ndGhfOyAKICAgICAgICAvKioKICAgICAgICAgKiBGbGFnIGluZGljYXRvciBpZiB0YXJnZXRUZXh0IHN0YXJ0cyB3aXRoIGFuIGFjY2VudAogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBib29sZWFuIG1faGFzUHJlZml4QWNjZW50c187CiAgICAgICAgLyoqCiAgICAgICAgICogRmxhZyBpbmRpY2F0b3IgaWYgdGFyZ2V0VGV4dCBlbmRzIHdpdGggYW4gYWNjZW50CiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gbV9oYXNTdWZmaXhBY2NlbnRzXzsKICAgICAgICAvKioKICAgICAgICAgKiBEZWZhdWx0IG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHNoaWZ0IGZvciBCb3llciBNb29yZQogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBpbnQgbV9kZWZhdWx0U2hpZnRTaXplXzsKICAgICAgICAvKioKICAgICAgICAgKiBOdW1iZXIgb2YgY2hhcmFjdGVycyB0byBzaGlmdCBmb3IgQm95ZXIgTW9vcmUsIGRlcGVuZGluZyBvbiB0aGUKICAgICAgICAgKiBzb3VyY2UgdGV4dCB0byBzZWFyY2gKICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgY2hhciBtX3NoaWZ0X1tdOwogICAgICAgIC8qKgogICAgICAgICAqIE51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHNoaWZ0IGJhY2t3YXJkcyBmb3IgQm95ZXIgTW9vcmUsIGRlcGVuZGluZyAKICAgICAgICAgKiBvbiB0aGUgc291cmNlIHRleHQgdG8gc2VhcmNoCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIGNoYXIgbV9iYWNrU2hpZnRfW107CiAgICAgICAgCiAgICAgICAgLy8gcHJvdGVjdGVkIGNvbnN0cnVjdG9ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAKICAgICAgICAvKioKICAgICAgICAgKiBFbXB0eSBjb25zdHJ1Y3RvciAKICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgUGF0dGVybihTdHJpbmcgcGF0dGVybikgCiAgICAgICAgewogICAgICAgIAl0YXJnZXRUZXh0ID0gcGF0dGVybjsKICAgICAgICAJbV9DRV8gPSBuZXcgaW50W0lOSVRJQUxfQVJSQVlfU0laRV9dOwkKICAgICAgICAJbV9DRUxlbmd0aF8gPSAwOwogICAgICAgIAltX2hhc1ByZWZpeEFjY2VudHNfID0gZmFsc2U7CiAgICAgICAgCW1faGFzU3VmZml4QWNjZW50c18gPSBmYWxzZTsKICAgICAgICAJbV9kZWZhdWx0U2hpZnRTaXplXyA9IDE7CQkKICAgICAgICAJbV9zaGlmdF8gPSBuZXcgY2hhcltNQVhfVEFCTEVfU0laRV9dOwogICAgICAgIAltX2JhY2tTaGlmdF8gPSBuZXcgY2hhcltNQVhfVEFCTEVfU0laRV9dOwogICAgICAgIH0KICAgIH07CgoKICAgIC8vIHByaXZhdGUgZGF0YSBtZW1iZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgCiAgICAvKioKICAgICAqIHRhcmdldCB0ZXh0IGJlZ2luIG9mZnNldC4gRWFjaCB0YXJnZXRUZXh0IGhhcyBhIHZhbGlkIGNvbnRpZ3VvdXMgcmVnaW9uIAogICAgICogdG8gaXRlcmF0ZSBhbmQgdGhpcyBkYXRhIG1lbWJlciBpcyB0aGUgb2Zmc2V0IHRvIHRoZSBmaXJzdCBzdWNoCiAgICAgKiBjaGFyYWN0ZXIgaW4gdGhlIHJlZ2lvbi4KICAgICAqLwogICAgcHJpdmF0ZSBpbnQgbV90ZXh0QmVnaW5PZmZzZXRfOwogICAgLyoqCiAgICAgKiB0YXJnZXQgdGV4dCBsaW1pdCBvZmZzZXQuIEVhY2ggdGFyZ2V0VGV4dCBoYXMgYSB2YWxpZCBjb250aWd1b3VzIHJlZ2lvbiAKICAgICAqIHRvIGl0ZXJhdGUgYW5kIHRoaXMgZGF0YSBtZW1iZXIgaXMgdGhlIG9mZnNldCB0byAxIGFmdGVyIHRoZSBsYXN0IHN1Y2gKICAgICAqIGNoYXJhY3RlciBpbiB0aGUgcmVnaW9uLgogICAgICovCiAgICBwcml2YXRlIGludCBtX3RleHRMaW1pdE9mZnNldF87CiAgICAvKioKICAgICAqIFVwb24gY29tcGxldGlvbiBvZiBhIHNlYXJjaCwgbV9tYXRjaEluZGV4XyB3aWxsIHN0b3JlIHN0YXJ0aW5nIG9mZnNldCBpbgogICAgICogbV90ZXh0IGZvciB0aGUgbWF0Y2guIFRoZSBWYWx1ZSBET05FIGlzIHRoZSBkZWZhdWx0IHZhbHVlLiAKICAgICAqIElmIHdlIGFyZSBub3QgYXQgdGhlIHN0YXJ0IG9mIHRoZSB0ZXh0IG9yIHRoZSBlbmQgb2YgdGhlIHRleHQgYW5kIAogICAgICogbV9tYXRjaGVkSW5kZXhfIGlzIERPTkUgaXQgbWVhbnMgdGhhdCB3ZSBjYW4gZmluZCBhbnkgbW9yZSBtYXRjaGVzIGluIAogICAgICogdGhhdCBwYXJ0aWN1bGFyIGRpcmVjdGlvbgogICAgICovCiAgICBwcml2YXRlIGludCBtX21hdGNoZWRJbmRleF87IAogICAgLyoqCiAgICAgKiBDdXJyZW50IHBhdHRlcm4gdG8gc2VhcmNoIGZvcgogICAgICovCiAgICBwcml2YXRlIFBhdHRlcm4gbV9wYXR0ZXJuXzsKICAgIC8qKgogICAgICogQ29sbGF0b3Igd2hvc2UgcnVsZXMgYXJlIHVzZWQgdG8gcGVyZm9ybSB0aGUgc2VhcmNoCiAgICAgKi8KICAgIHByaXZhdGUgUnVsZUJhc2VkQ29sbGF0b3IgbV9jb2xsYXRvcl87CiAgICAvKiogCiAgICAgKiBUaGUgY29sbGF0aW9uIGVsZW1lbnQgaXRlcmF0b3IgZm9yIHRoZSB0ZXh0IHNvdXJjZS4KICAgICAqLwogICAgcHJpdmF0ZSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgbV9jb2xFSXRlcl87CiAgICAvKiogCiAgICAgKiBVdGlsaXR5IGNvbGxhdGlvbiBlbGVtZW50LCB1c2VkIHRocm91Z2hvdXQgcHJvZ3JhbSBmb3IgdGVtcG9yYXJ5IAogICAgICogaXRlcmF0aW9uLgogICAgICovCiAgICBwcml2YXRlIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBtX3V0aWxDb2xFSXRlcl87CiAgICAvKioKICAgICAqIFRoZSBtYXNrIHVzZWQgb24gdGhlIGNvbGxhdGlvbiBlbGVtZW50cyB0byByZXRyaWV2ZSB0aGUgdmFsaWQgc3RyZW5ndGgKICAgICAqIHdlaWdodCAKICAgICAqLwogICAgcHJpdmF0ZSBpbnQgbV9jZU1hc2tfOwogICAgLyoqCiAgICAgKiBCdWZmZXIgc3RvcmluZyBhY2NlbnRzIGR1cmluZyBhIGNhbm9uaWNhbCBzZWFyY2gKICAgICAqLwogICAgcHJpdmF0ZSBTdHJpbmdCdWZmZXIgbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXzsKICAgIC8qKgogICAgICogQnVmZmVyIHN0b3JpbmcgYWNjZW50cyBkdXJpbmcgYSBjYW5vbmljYWwgc2VhcmNoCiAgICAgKi8KICAgIHByaXZhdGUgU3RyaW5nQnVmZmVyIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c187CiAgICAvKioKICAgICAqIEZsYWcgdG8gaW5kaWNhdGUgaWYgY2Fub25pY2FsIHNlYXJjaCBpcyB0byBiZSBkb25lLgogICAgICogRS5nIGxvb2tpbmcgZm9yICJhXHUwMzAwIiBpbiAiYVx1MDMxOFx1MDMwMCIgd2lsbCB5aWVsZCB0aGUgbWF0Y2ggYXQgMC4KICAgICAqLwogICAgcHJpdmF0ZSBib29sZWFuIG1faXNDYW5vbmljYWxNYXRjaF87CiAgICAvKioKICAgICAqIFNpemUgb2YgdGhlIHNoaWZ0IHRhYmxlcwogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFYX1RBQkxFX1NJWkVfID0gMjU3OyAKICAgIC8qKgogICAgICogSW5pdGlhbCBhcnJheSBzaXplCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTklUSUFMX0FSUkFZX1NJWkVfID0gMjU2OwogICAgLyoqCiAgICAgKiBVdGlsaXR5IG1hc2sKICAgICAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNFQ09ORF9MQVNUX0JZVEVfU0hJRlRfID0gODsKCS8qKgogICAgICogVXRpbGl0eSBtYXNrCiAgICAgKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBMQVNUX0JZVEVfTUFTS18gPSAweGZmOwoJLyoqCgkgKiBVdGlsaXR5IGJ1ZmZlciBmb3IgcmV0dXJuIHZhbHVlcyBhbmQgdGVtcG9yYXJ5IHN0b3JhZ2UKCSAqLwoJcHJpdmF0ZSBpbnQgbV91dGlsQnVmZmVyX1tdID0gbmV3IGludFsyXTsKCgkvLyBwcml2YXRlIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIC8qKgogICAgICogSGFzaCBhIGNvbGxhdGlvbiBlbGVtZW50IGZyb20gaXRzIGZ1bGwgc2l6ZSAoMzIgYml0cykgZG93biBpbnRvIGEKICAgICAqIHZhbHVlIHRoYXQgY2FuIGJlIHVzZWQgYXMgYW4gaW5kZXggaW50byB0aGUgc2hpZnQgdGFibGVzLiAgUmlnaHQKICAgICAqIG5vdyB3ZSBkbyBhIG1vZHVsdXMgYnkgdGhlIHNpemUgb2YgdGhlIGhhc2ggdGFibGUuCiAgICAgKiBAcGFyYW0gY2UgY29sbGF0aW9uIGVsZW1lbnQKCSAqIEByZXR1cm4gY29sbGFwc2VkIHZlcnNpb24gb2YgdGhlIGNvbGxhdGlvbiBlbGVtZW50CiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBoYXNoKGludCBjZSkgCiAgICB7CiAgICAgICAgLy8gdGhlIG9sZCB2YWx1ZSBVQ09MX1BSSU1BUllPUkRFUihjZSkgJSBNQVhfVEFCTEVfU0laRV8gZG9lcyBub3Qgd29yawogICAgCS8vIHdlbGwgd2l0aCB0aGUgbmV3IGNvbGxhdGlvbiB3aGVyZSBtb3N0IG9mIHRoZSBsYXRpbiAxIGNoYXJhY3RlcnMKICAgIAkvLyBhcmUgb2YgdGhlIHZhbHVlIHh4MDAweHh4LiB0aGVpciBoYXNoZXMgd2lsbCBtb3N0IG9mIHRoZSB0aW1lIGJlIDAKICAgIAkvLyB0byBiZSBkaXNjdXNzZWQgb24gdGhlIGhhc2ggYWxnby4KICAgIAlyZXR1cm4gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLnByaW1hcnlPcmRlcihjZSkgJSBNQVhfVEFCTEVfU0laRV87CiAgICB9CiAgICAKICAgIC8qKgoJICogR2V0cyB0aGUgZmNkIHZhbHVlIGZvciBhIGNoYXJhY3RlciBhdCB0aGUgYXJndW1lbnQgaW5kZXguCgkgKiBUaGlzIG1ldGhvZCB0YWtlcyBpbnRvIGFjY291bnRzIG9mIHRoZSBzdXBwbGVtZW50YXJ5IGNoYXJhY3RlcnMuCgkgKiBOb3RlIHRoaXMgbWV0aG9kIGNoYW5nZXMgdGhlIG9mZnNldCBpbiB0aGUgY2hhcmFjdGVyIGl0ZXJhdG9yLgoJICogQHBhcmFtIHN0ciBVVEYxNiBzdHJpbmcgd2hlcmUgY2hhcmFjdGVyIGZvciBmY2QgcmV0cmlldmFsIHJlc2lkZXMKCSAqIEBwYXJhbSBvZmZzZXQgcG9zaXRpb24gb2YgdGhlIGNoYXJhY3RlciB3aG9zZSBmY2QgaXMgdG8gYmUgcmV0cmlldmVkCgkgKiBAcmV0dXJuIGZjZCB2YWx1ZQoJICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIGdldEZDRChDaGFyYWN0ZXJJdGVyYXRvciBzdHIsIGludCBvZmZzZXQpCgl7CgkgICAgc3RyLnNldEluZGV4KG9mZnNldCk7CgkgICAgY2hhciBjaCA9IHN0ci5jdXJyZW50KCk7CgkgICAgY2hhciByZXN1bHQgPSBOb3JtYWxpemVySW1wbC5nZXRGQ0QxNihjaCk7CgkgICAgCgkgICAgaWYgKChyZXN1bHQgIT0gMCkgJiYgKHN0ci5nZXRFbmRJbmRleCgpICE9IG9mZnNldCArIDEpICYmIAoJICAgIAlVVEYxNi5pc0xlYWRTdXJyb2dhdGUoY2gpKSB7CgkgICAgICAgIGNoID0gc3RyLm5leHQoKTsKCSAgICAgICAgaWYgKFVURjE2LmlzVHJhaWxTdXJyb2dhdGUoY2gpKSB7CgkgICAgICAgICAgICByZXN1bHQgPSBOb3JtYWxpemVySW1wbC5nZXRGQ0QxNkZyb21TdXJyb2dhdGVQYWlyKHJlc3VsdCwgY2gpOwoJICAgICAgICB9IGVsc2UgewoJICAgICAgICAgICAgcmVzdWx0ID0gMDsKCSAgICAgICAgfQoJICAgIH0KCSAgICByZXR1cm4gcmVzdWx0OwoJfQoJCgkvKioKCSAqIEdldHMgdGhlIGZjZCB2YWx1ZSBmb3IgYSBjaGFyYWN0ZXIgYXQgdGhlIGFyZ3VtZW50IGluZGV4LgoJICogVGhpcyBtZXRob2QgdGFrZXMgaW50byBhY2NvdW50cyBvZiB0aGUgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzLgoJICogQHBhcmFtIHN0ciBVVEYxNiBzdHJpbmcgd2hlcmUgY2hhcmFjdGVyIGZvciBmY2QgcmV0cmlldmFsIHJlc2lkZXMKCSAqIEBwYXJhbSBvZmZzZXQgcG9zaXRpb24gb2YgdGhlIGNoYXJhY3RlciB3aG9zZSBmY2QgaXMgdG8gYmUgcmV0cmlldmVkCgkgKiBAcmV0dXJuIGZjZCB2YWx1ZQoJICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIGdldEZDRChTdHJpbmcgc3RyLCBpbnQgb2Zmc2V0KQoJewoJICAgIGNoYXIgY2ggPSBzdHIuY2hhckF0KG9mZnNldCk7CgkgICAgY2hhciByZXN1bHQgPSBOb3JtYWxpemVySW1wbC5nZXRGQ0QxNihjaCk7CgkgICAgCgkgICAgaWYgKChyZXN1bHQgIT0gMCkgJiYgKHN0ci5sZW5ndGgoKSAhPSBvZmZzZXQgKyAxKSAmJiAKCSAgICAJVVRGMTYuaXNMZWFkU3Vycm9nYXRlKGNoKSkgewoJICAgICAgICBjaCA9IHN0ci5jaGFyQXQob2Zmc2V0ICsgMSk7CgkgICAgICAgIGlmIChVVEYxNi5pc1RyYWlsU3Vycm9nYXRlKGNoKSkgewoJICAgICAgICAgICAgcmVzdWx0ID0gTm9ybWFsaXplckltcGwuZ2V0RkNEMTZGcm9tU3Vycm9nYXRlUGFpcihyZXN1bHQsIGNoKTsKCSAgICAgICAgfSBlbHNlIHsKCSAgICAgICAgICAgIHJlc3VsdCA9IDA7CgkgICAgICAgIH0KCSAgICB9CgkgICAgcmV0dXJuIHJlc3VsdDsKCX0KCQoJLyoqCgkqIEdldHRpbmcgdGhlIG1vZGlmaWVkIGNvbGxhdGlvbiBlbGVtZW50cyB0YWtpbmcgaW50byBhY2NvdW50IHRoZSBjb2xsYXRpb24gCgkqIGF0dHJpYnV0ZXMKCSogQHBhcmFtIGNlIAoJKiBAcmV0dXJuIHRoZSBtb2RpZmllZCBjb2xsYXRpb24gZWxlbWVudAoJKi8KCXByaXZhdGUgZmluYWwgaW50IGdldENFKGludCBjZSkKCXsKCSAgICAvLyBub3RlIGZvciB0ZXJ0aWFyeSB3ZSBjYW4ndCB1c2UgdGhlIGNvbGxhdG9yLT50ZXJ0aWFyeU1hc2ssIHRoYXQKCSAgICAvLyBpcyBhIHByZXByb2Nlc3NlZCBtYXNrIHRoYXQgdGFrZXMgaW50byBhY2NvdW50IGNhc2Ugb3B0aW9ucy4gc2luY2UKCSAgICAvLyB3ZSBhcmUgb25seSBjb25jZXJuZWQgd2l0aCBleGFjdCBtYXRjaGVzLCB3ZSBkb24ndCBuZWVkIHRoYXQuCgkgICAgY2UgJj0gbV9jZU1hc2tfOwoJICAgIAoJICAgIGlmIChtX2NvbGxhdG9yXy5pc0FsdGVybmF0ZUhhbmRsaW5nU2hpZnRlZCgpKSB7CgkgICAgICAgIC8vIGFsdGVybmF0ZSBoYW5kbGluZyBoZXJlLCBzaW5jZSBvbmx5IHRoZSAxNiBtb3N0IHNpZ25pZmljYW50IAoJICAgICAgICAvLyBkaWdpdHMgaXMgb25seSB1c2VkLCB3ZSBjYW4gc2FmZWx5IGRvIGEgY29tcGFyZSB3aXRob3V0IG1hc2tpbmcKCSAgICAgICAgLy8gaWYgdGhlIGNlIGlzIGEgdmFyaWFibGUsIHdlIG1hc2sgYW5kIGdldCBvbmx5IHRoZSBwcmltYXJ5IHZhbHVlcwoJICAgICAgICAvLyBubyBzaGlmdGluZyB0byBxdWFydGVuYXJ5IGlzIHJlcXVpcmVkIHNpbmNlIGFsbCBwcmltYXJ5IHZhbHVlcwoJICAgICAgICAvLyBsZXNzIHRoYW4gdmFyaWFibGV0b3Agd2lsbCBuZWVkIHRvIGJlIG1hc2tlZCBvZmYgYW55d2F5LgoJICAgICAgICBpZiAoKG1fY29sbGF0b3JfLm1fdmFyaWFibGVUb3BWYWx1ZV8gIDw8IDE2KSA+IGNlKSB7CgkgICAgICAgICAgICBpZiAobV9jb2xsYXRvcl8uZ2V0U3RyZW5ndGgoKSA9PSBDb2xsYXRvci5RVUFURVJOQVJZKSB7CgkgICAgICAgICAgICAgICAgY2UgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IucHJpbWFyeU9yZGVyKGNlKTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGVsc2UgeyAKCSAgICAgICAgICAgICAgICBjZSA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEU7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkKCSAgICByZXR1cm4gY2U7Cgl9CgkKCS8qKgoJICogQXBwZW5kcyBhIGludCB0byBhIGludCBhcnJheSwgaW5jcmVhc2luZyB0aGUgc2l6ZSBvZiB0aGUgYXJyYXkgd2hlbiAKCSAqIHdlIGFyZSBvdXQgb2Ygc3BhY2UuCgkgKiBAcGFyYW0gb2Zmc2V0IGluIGFycmF5IHRvIGFwcGVuZCB0bwoJICogQHBhcmFtIHZhbHVlIHRvIGFwcGVuZAoJICogQHBhcmFtIGFycmF5IHRvIGFwcGVuZCB0bwoJICogQHJldHVybiB0aGUgYXJyYXkgYXBwZW5kZWQgdG8sIHRoaXMgY291bGQgYmUgYSBuZXcgYW5kIGJpZ2dlciBhcnJheQoJICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnRbXSBhcHBlbmQoaW50IG9mZnNldCwgaW50IHZhbHVlLCBpbnQgYXJyYXlbXSkKCXsKCQlpZiAob2Zmc2V0ID49IGFycmF5Lmxlbmd0aCkgewoJCQlpbnQgdGVtcFtdID0gbmV3IGludFtvZmZzZXQgKyBJTklUSUFMX0FSUkFZX1NJWkVfXTsKCQkJU3lzdGVtLmFycmF5Y29weShhcnJheSwgMCwgdGVtcCwgMCwgYXJyYXkubGVuZ3RoKTsKCQkJYXJyYXkgPSB0ZW1wOwoJCX0KCQlhcnJheVtvZmZzZXRdID0gdmFsdWU7CgkJcmV0dXJuIGFycmF5OwoJfQoJCgkvKioKCSAqIEluaXRpYWxpemluZyB0aGUgY2UgdGFibGUgZm9yIGEgcGF0dGVybi4gU3RvcmVzIG5vbi1pZ25vcmFibGUgY29sbGF0aW9uIAoJICoga2V5cy4gVGFibGUgc2l6ZSB3aWxsIGJlIGVzdGltYXRlZCBieSB0aGUgc2l6ZSBvZiB0aGUgcGF0dGVybiB0ZXh0LiAKCSAqIFRhYmxlIGV4cGFuc2lvbiB3aWxsIGJlIHBlcmZvcm0gYXMgd2UgZ28gYWxvbmcuIEFkZGluZyAxIHRvIGVuc3VyZSB0aGF0IAoJICogdGhlIHRhYmxlIHNpemUgZGVmaW5pdGVseSBpbmNyZWFzZXMuCgkgKiBJbnRlcm5hbCBtZXRob2QsIHN0YXR1cyBhc3N1bWVkIHRvIGJlIGEgc3VjY2Vzcy4KCSAqIEByZXR1cm4gdG90YWwgbnVtYmVyIG9mIGV4cGFuc2lvbnMgCgkgKi8KCXByaXZhdGUgZmluYWwgaW50IGluaXRpYWxpemVQYXR0ZXJuQ0VUYWJsZSgpCgl7CgkgICAgbV91dGlsQ29sRUl0ZXJfLnNldFRleHQobV9wYXR0ZXJuXy50YXJnZXRUZXh0KTsKCSAgICAKCSAgICBpbnQgb2Zmc2V0ID0gMDsKCSAgICBpbnQgcmVzdWx0ID0gMDsKCSAgICBpbnQgY2UgPSBtX3V0aWxDb2xFSXRlcl8ubmV4dCgpOwoJCgkgICAgd2hpbGUgKGNlICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKCSAgICAgICAgaW50IG5ld2NlID0gZ2V0Q0UoY2UpOwoJICAgICAgICBpZiAobmV3Y2UgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgbV9wYXR0ZXJuXy5tX0NFXyA9IGFwcGVuZChvZmZzZXQsIG5ld2NlLCBtX3BhdHRlcm5fLm1fQ0VfKTsKCSAgICAgICAgICAgIG9mZnNldCArKzsJICAgICAgICAKCSAgICAgICAgfQoJICAgICAgICByZXN1bHQgKz0gbV91dGlsQ29sRUl0ZXJfLmdldE1heEV4cGFuc2lvbihjZSkgLSAxOwoJICAgICAgICBjZSA9IG1fdXRpbENvbEVJdGVyXy5uZXh0KCk7CgkgICAgfQoJCgkgICAgbV9wYXR0ZXJuXy5tX0NFXyA9IGFwcGVuZChvZmZzZXQsIDAsIG1fcGF0dGVybl8ubV9DRV8pOwoJICAgIG1fcGF0dGVybl8ubV9DRUxlbmd0aF8gPSBvZmZzZXQ7CgkKCSAgICByZXR1cm4gcmVzdWx0OwoJfQoJCgkvKioKCSAqIEluaXRpYWxpemVzIHRoZSBwYXR0ZXJuIHN0cnVjdC4KCSAqIEludGVybmFsIG1ldGhvZCwgc3RhdHVzIGFzc3VtZWQgdG8gYmUgc3VjY2Vzcy4KCSAqIEByZXR1cm4gZXhwYW5zaW9uc2l6ZSB0aGUgdG90YWwgZXhwYW5zaW9uIHNpemUgb2YgdGhlIHBhdHRlcm4KCSAqLyAKCXByaXZhdGUgZmluYWwgaW50IGluaXRpYWxpemVQYXR0ZXJuKCkKCXsKCSAgICBtX3BhdHRlcm5fLm1faGFzUHJlZml4QWNjZW50c18gPSAoZ2V0RkNEKG1fcGF0dGVybl8udGFyZ2V0VGV4dCwgMCkgCgkgICAgCQkJCQkJCQkJID4+IFNFQ09ORF9MQVNUX0JZVEVfU0hJRlRfKSAhPSAwOwoJICAgIG1fcGF0dGVybl8ubV9oYXNTdWZmaXhBY2NlbnRzXyA9IChnZXRGQ0QobV9wYXR0ZXJuXy50YXJnZXRUZXh0LCAKCSAgICAJCQkJCQkJCQkJIG1fcGF0dGVybl8udGFyZ2V0VGV4dC5sZW5ndGgoKSAKCSAgICAJCQkJCQkJCQkJIC0gMSkgCgkgICAgCQkJCQkJCQkJJiBMQVNUX0JZVEVfTUFTS18pICE9IDA7CgkgICAgLy8gc2luY2UgaW50aWFsaXplUGF0dGVybiBpcyBhbiBpbnRlcm5hbCBtZXRob2Qgc3RhdHVzIGlzIGEgc3VjY2Vzcy4KCSAgICByZXR1cm4gaW5pdGlhbGl6ZVBhdHRlcm5DRVRhYmxlKCk7ICAgCgl9CgkKCS8qKgoJICogSW5pdGlhbGl6aW5nIHNoaWZ0IHRhYmxlcywgd2l0aCB0aGUgZGVmYXVsdCB2YWx1ZXMuCgkgKiBJZiBhIGNvcnJlc3BvbmRpbmcgZGVmYXVsdCB2YWx1ZSBpcyAwLCB0aGUgc2hpZnQgdGFibGUgaXMgbm90IHNldC4KCSAqIEBwYXJhbSBzaGlmdCB0YWJsZSBmb3IgZm9yd2FyZHMgc2hpZnQgCgkgKiBAcGFyYW0gYmFja3NoaWZ0IHRhYmxlIGZvciBiYWNrd2FyZHMgc2hpZnQKCSAqIEBwYXJhbSBjZXRhYmxlIHRhYmxlIGNvbnRhaW5pbmcgcGF0dGVybiBjZQoJICogQHBhcmFtIGNlc2l6ZSBzaXplIG9mIHRoZSBwYXR0ZXJuIGNlcwoJICogQHBhcmFtIGV4cGFuc2lvbnNpemUgdG90YWwgc2l6ZSBvZiB0aGUgZXhwYW5zaW9ucwoJICogQHBhcmFtIGRlZmF1bHRmb3J3YXJkIHRoZSBkZWZhdWx0IGZvcndhcmQgdmFsdWUKCSAqIEBwYXJhbSBkZWZhdWx0YmFja3dhcmQgdGhlIGRlZmF1bHQgYmFja3dhcmQgdmFsdWUKCSAqLwoJIHByaXZhdGUgZmluYWwgdm9pZCBzZXRTaGlmdFRhYmxlKGNoYXIgc2hpZnRbXSwgCgkgCQkJCQkJCQkJCQkgICBjaGFyIGJhY2tzaGlmdFtdLCAKCQkJCQkgICAgICAgICAgICAgICAgICAgICAgICAgCSAgIGludCBjZXRhYmxlW10sIGludCBjZXNpemUsIAogICAgICAgICAgICAgICAgICAgICAgICAgIAkJCQkJIAkgICBpbnQgZXhwYW5zaW9uc2l6ZSwKCQkJCQkgICAgICAgICAgICAgICAgICAgICAgICAgCSAgIGNoYXIgZGVmYXVsdGZvcndhcmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgCQkJCQkgCSAgIGNoYXIgZGVmYXVsdGJhY2t3YXJkKQoJewoJICAgIC8vIGVzdGltYXRlIHRoZSB2YWx1ZSB0byBzaGlmdC4gdG8gZG8gdGhhdCB3ZSBlc3RpbWF0ZSB0aGUgc21hbGxlc3QgCgkgICAgLy8gbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gZ2l2ZSB0aGUgcmVsZXZhbnQgY2VzLCBpZSBhcHByb3hpbWF0ZWx5CgkgICAgLy8gdGhlIG51bWJlciBvZiBjZXMgbWludXMgdGhlaXIgZXhwYW5zaW9uLCBzaW5jZSBleHBhbnNpb25zIGNhbiBjb21lIAoJICAgIC8vIGZyb20gYSBjaGFyYWN0ZXIuCgkgICAgZm9yIChpbnQgY291bnQgPSAwOyBjb3VudCA8IE1BWF9UQUJMRV9TSVpFXzsgY291bnQgKyspIHsKCSAgICAgICAgc2hpZnRbY291bnRdID0gZGVmYXVsdGZvcndhcmQ7CgkgICAgfQoJICAgIGNlc2l6ZSAtLTsgLy8gZG93biB0byB0aGUgbGFzdCBpbmRleAoJICAgIGZvciAoaW50IGNvdW50ID0gMDsgY291bnQgPCBjZXNpemU7IGNvdW50ICsrKSB7CgkgICAgICAgIC8vIG51bWJlciBvZiBjZXMgZnJvbSByaWdodCBvZiBhcnJheSB0byB0aGUgY291bnQKCSAgICAgICAgaW50IHRlbXAgPSBkZWZhdWx0Zm9yd2FyZCAtIGNvdW50IC0gMTsKCSAgICAgICAgc2hpZnRbaGFzaChjZXRhYmxlW2NvdW50XSldID0gdGVtcCA+IDEgPyAoKGNoYXIpdGVtcCkgOiAxOwoJICAgIH0KCSAgICBzaGlmdFtoYXNoKGNldGFibGVbY2VzaXplXSldID0gMTsKCSAgICAvLyBmb3IgaWdub3JhYmxlcyB3ZSBqdXN0IHNoaWZ0IGJ5IG9uZS4gc2VlIHRlc3QgZXhhbXBsZXMuCgkgICAgc2hpZnRbaGFzaCgwKV0gPSAxOwoJICAgIAoJICAgIGZvciAoaW50IGNvdW50ID0gMDsgY291bnQgPCBNQVhfVEFCTEVfU0laRV87IGNvdW50ICsrKSB7CgkgICAgICAgIGJhY2tzaGlmdFtjb3VudF0gPSBkZWZhdWx0YmFja3dhcmQ7CgkgICAgfQoJICAgIGZvciAoaW50IGNvdW50ID0gY2VzaXplOyBjb3VudCA+IDA7IGNvdW50IC0tKSB7CgkgICAgICAgIC8vIHRoZSBvcmlnaW5hbCB2YWx1ZSBjb3VudCBkb2VzIG5vdCBzZWVtIHRvIHdvcmsKCSAgICAgICAgYmFja3NoaWZ0W2hhc2goY2V0YWJsZVtjb3VudF0pXSA9IChjaGFyKShjb3VudCA+IGV4cGFuc2lvbnNpemUgPyAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAkJY291bnQgLSBleHBhbnNpb25zaXplIDogMSk7CgkgICAgfQoJICAgIGJhY2tzaGlmdFtoYXNoKGNldGFibGVbMF0pXSA9IDE7CgkgICAgYmFja3NoaWZ0W2hhc2goMCldID0gMTsKCX0KCQoJLyoqCgkgKiA8cD5CdWlsZGluZyBvZiB0aGUgcGF0dGVybiBjb2xsYXRpb24gZWxlbWVudCBsaXN0IGFuZCB0aGUgQm95ZXIgTW9vcmUgCgkgKiBTdHJpbmdTZWFyY2ggdGFibGUuPC9wPgoJICogPHA+VGhlIGNhbm9uaWNhbCBtYXRjaCB3aWxsIG9ubHkgYmUgcGVyZm9ybWVkIGFmdGVyIHRoZSBkZWZhdWx0IG1hdGNoIAoJICogZmFpbHMuPC9wPgoJICogPHA+Rm9yIGJvdGggY2FzZXMgd2UgbmVlZCB0byByZW1lbWJlciB0aGUgc2l6ZSBvZiB0aGUgY29tcG9zZWQgYW5kIAoJICogZGVjb21wb3NlZCB2ZXJzaW9ucyBvZiB0aGUgc3RyaW5nLiBTaW5jZSB0aGUgQm95ZXItTW9vcmUgc2hpZnQgCgkgKiBjYWxjdWxhdGlvbnMgc2hpZnRzIGJ5IGEgbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gdGhlIHRleHQgYW5kIHRyaWVzIHRvIAoJICogbWF0Y2ggdGhlIHBhdHRlcm4gZnJvbSB0aGF0IG9mZnNldCwgdGhlIHNoaWZ0IHZhbHVlIGNhbiBub3QgYmUgdG9vIGxhcmdlIAoJICogaW4gY2FzZSB3ZSBtaXNzIHNvbWUgY2hhcmFjdGVycy4gVG8gY2hvb3NlIGEgcmlnaHQgc2hpZnQgc2l6ZSwgd2UgCgkgKiBlc3RpbWF0ZSB0aGUgTkZDIGZvcm0gb2YgdGhlIGFuZCB1c2UgaXRzIHNpemUgYXMgYSBzaGlmdCBndWlkZS4gVGhlIE5GQyAKCSAqIGZvcm0gc2hvdWxkIGJlIHRoZSBzbWFsbCBwb3NzaWJsZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGF0dGVybi4gQW55d2F5cywgCgkgKiB3ZSdsbCBlcnIgb24gdGhlIHNtYWxsZXIgc2hpZnQgc2l6ZS4gSGVuY2UgdGhlIGNhbGN1bGF0aW9uIGZvciAKCSAqIG1pbmxlbmd0aC4gQ2Fub25pY2FsIG1hdGNoIHdpbGwgYmUgcGVyZm9ybWVkIHNsaWdodGx5IGRpZmZlcmVudGx5LiBXZSdsbCAKCSAqIHNwbGl0IHRoZSBwYXR0ZXJuIGludG8gMyBwYXJ0cywgdGhlIHByZWZpeCBhY2NlbnRzIChQQSksIHRoZSBtaWRkbGUgCgkgKiBzdHJpbmcgYm91bmRlZCBieSB0aGUgZmlyc3QgYW5kIGxhc3QgYmFzZSBjaGFyYWN0ZXIgKE1TKSwgdGhlIGVuZGluZyAKCSAqIGFjY2VudHMgKEVBKS4gTWF0Y2hlcyB3aWxsIGJlIGRvbmUgb24gTVMgZmlyc3QsIGFuZCBvbmx5IHdoZW4gd2UgbWF0Y2ggCgkgKiBNUyB0aGVuIHNvbWUgcHJvY2Vzc2luZyB3aWxsIGJlIHJlcXVpcmVkIGZvciB0aGUgcHJlZml4IGFuZCBlbmQgYWNjZW50cyAKCSAqIGluIG9yZGVyIHRvIGRldGVybWluZSBpZiB0aGV5IG1hdGNoIFBBIGFuZCBFQS4gSGVuY2UgdGhlIGRlZmF1bHQgc2hpZnQgCgkgKiB2YWx1ZXMgZm9yIHRoZSBjYW5vbmljYWwgbWF0Y2ggd2lsbCB0YWtlIHRoZSBzaXplIG9mIGVpdGhlciBlbmQncyBhY2NlbnQgCgkgKiBpbnRvIGNvbnNpZGVyYXRpb24uIEZvcndhcmRzIHNlYXJjaCB3aWxsIHRha2UgdGhlIGVuZCBhY2NlbnRzIGludG8gCgkgKiBjb25zaWRlcmF0aW9uIGZvciB0aGUgZGVmYXVsdCBzaGlmdCB2YWx1ZXMgYW5kIHRoZSBiYWNrd2FyZHMgc2VhcmNoIHdpbGwgCgkgKiB0YWtlIHRoZSBwcmVmaXggYWNjZW50cyBpbnRvIGNvbnNpZGVyYXRpb24uPC9wPgoJICogPHA+SWYgcGF0dGVybiBoYXMgbm8gbm9uLWlnbm9yYWJsZSBjZSwgd2UgcmV0dXJuIGEgaWxsZWdhbCBhcmd1bWVudCAKCSAqIGVycm9yLjwvcD4KCSAqLyAKCXByaXZhdGUgZmluYWwgdm9pZCBpbml0aWFsaXplKCkKCXsKCSAgICBpbnQgZXhwYW5kbGVuZ3RoICA9IGluaXRpYWxpemVQYXR0ZXJuKCk7ICAgCgkgICAgaWYgKG1fcGF0dGVybl8ubV9DRUxlbmd0aF8gPiAwKSB7CgkgICAgICAgIGNoYXIgbWlubGVuZ3RoID0gKGNoYXIpKG1fcGF0dGVybl8ubV9DRUxlbmd0aF8gPiBleHBhbmRsZW5ndGggCgkgICAgICAgIAkJCQkJPyBtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfIC0gZXhwYW5kbGVuZ3RoIDogMSk7CgkgICAgICAgIG1fcGF0dGVybl8ubV9kZWZhdWx0U2hpZnRTaXplXyA9IG1pbmxlbmd0aDsKICAgICAgICAgICAgc2V0U2hpZnRUYWJsZShtX3BhdHRlcm5fLm1fc2hpZnRfLCBtX3BhdHRlcm5fLm1fYmFja1NoaWZ0XywgCgkgICAgICAgIAkJCSAgbV9wYXR0ZXJuXy5tX0NFXywgbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXywgCgkgICAgICAgIAkJCSAgZXhwYW5kbGVuZ3RoLCBtaW5sZW5ndGgsIG1pbmxlbmd0aCk7CgkgICAgfQoJICAgIGVsc2UgewoJICAgIAltX3BhdHRlcm5fLm1fZGVmYXVsdFNoaWZ0U2l6ZV8gPSAwOwoJICAgIH0KCX0KCQoJLyoqCgkgKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgc2VhcmNoIHRleHQgYm91bmRlZCBieSB0aGUgb2Zmc2V0IHN0YXJ0IGFuZCBlbmQgaXMgCgkgKiBvbmUgb3IgbW9yZSB3aG9sZSB1bml0cyBvZiB0ZXh0IGFzIGRldGVybWluZWQgYnkgdGhlIGJyZWFraXRlcmF0b3IgaW4gCgkgKiBTdHJpbmdTZWFyY2guCgkgKiBAcGFyYW0gc3RhcnQgdGFyZ2V0IHRleHQgc3RhcnQgb2Zmc2V0CgkgKiBAcGFyYW0gZW5kIHRhcmdldCB0ZXh0IGVuZCBvZmZzZXQKCSAqLwoJcHJpdmF0ZSBmaW5hbCBib29sZWFuIGlzQnJlYWtVbml0KGludCBzdGFydCwgaW50IGVuZCkgCgl7CgkgICAgaWYgKGJyZWFrSXRlcmF0b3IgIT0gbnVsbCkgewoJICAgICAgICBpbnQgc3RhcnRpbmRleCA9IGJyZWFrSXRlcmF0b3IuZmlyc3QoKTsKCSAgICAgICAgaW50IGVuZGluZGV4ICAgPSBicmVha0l0ZXJhdG9yLmxhc3QoKTsKCSAgICAgICAgCgkgICAgICAgIC8vIG91dC1vZi1yYW5nZSBpbmRleGVzIGFyZSBuZXZlciBib3VuZGFyeSBwb3NpdGlvbnMKCSAgICAgICAgaWYgKHN0YXJ0IDwgc3RhcnRpbmRleCB8fCBzdGFydCA+IGVuZGluZGV4IHx8IGVuZCA8IHN0YXJ0aW5kZXggCgkgICAgICAgIAl8fCBlbmQgPiBlbmRpbmRleCkgewoJICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoJICAgICAgICB9CgkgICAgICAgIC8vIG90aGVyd2lzZSwgd2UgY2FuIHVzZSBmb2xsb3dpbmcoKSBvbiB0aGUgcG9zaXRpb24gYmVmb3JlIHRoZSAKCSAgICAgICAgLy8gc3BlY2lmaWVkIG9uZSBhbmQgcmV0dXJuIHRydWUgb2YgdGhlIHBvc2l0aW9uIHdlIGdldCBiYWNrIGlzIHRoZSAKCSAgICAgICAgLy8gb25lIHRoZSB1c2VyIHNwZWNpZmllZAoJICAgICAgICBib29sZWFuIHJlc3VsdCA9IChzdGFydCA9PSBzdGFydGluZGV4IAoJICAgICAgICAJCQkJICB8fCBicmVha0l0ZXJhdG9yLmZvbGxvd2luZyhzdGFydCAtIDEpID09IHN0YXJ0KSAKCSAgICAgICAgCQkJCSAmJiAoZW5kID09IGVuZGluZGV4IAoJICAgICAgICAJCQkJIAkgfHwgYnJlYWtJdGVyYXRvci5mb2xsb3dpbmcoZW5kIC0gMSkgPT0gZW5kKTsKCSAgICAgICAgaWYgKHJlc3VsdCkgewoJICAgICAgICAgICAgLy8gaXRlcmF0ZXMgdGhlIGluZGl2aWR1YWwgY2VzCgkgICAgICAgICAgICBtX3V0aWxDb2xFSXRlcl8uc2V0VGV4dCh0YXJnZXRUZXh0LCBzdGFydCk7CgkgICAgICAgICAgICBmb3IgKGludCBjb3VudCA9IDA7IGNvdW50IDwgbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXzsKCSAgICAgICAgICAgICAgICAgY291bnQgKyspIHsKICAgICAgICAgICAgICAgICAgICBpbnQgY2UgPSBnZXRDRShtX3V0aWxDb2xFSXRlcl8ubmV4dCgpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoY2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewogICAgICAgICAgICAgICAgICAgICAgICBjb3VudCAtLTsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgIGlmIChjZSAhPSBtX3BhdHRlcm5fLm1fQ0VfW2NvdW50XSkgewoJICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW50IG5leHRjZSA9IG1fdXRpbENvbEVJdGVyXy5uZXh0KCk7CiAgICAgICAgICAgICAgICB3aGlsZSAobV91dGlsQ29sRUl0ZXJfLmdldE9mZnNldCgpID09IGVuZCAKICAgICAgICAgICAgICAgICAgICAgICAmJiBnZXRDRShuZXh0Y2UpID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKICAgICAgICAgICAgICAgICAgICBuZXh0Y2UgPSBtX3V0aWxDb2xFSXRlcl8ubmV4dCgpOyAgICAgICAKICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGlmIChuZXh0Y2UgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUiAKCSAgICAgICAgICAgIAkmJiBtX3V0aWxDb2xFSXRlcl8uZ2V0T2Zmc2V0KCkgPT0gZW5kKSB7CgkgICAgICAgICAgICAgICAgLy8gZXh0cmEgY29sbGF0aW9uIGVsZW1lbnRzIGF0IHRoZSBlbmQgb2YgdGhlIG1hdGNoCgkgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgICAgIHJldHVybiByZXN1bHQ7CgkgICAgfQoJICAgIHJldHVybiB0cnVlOwoJfQoJCgkvKioKCSAqIEdldHRpbmcgdGhlIG5leHQgYmFzZSBjaGFyYWN0ZXIgb2Zmc2V0IGlmIGN1cnJlbnQgb2Zmc2V0IGlzIGFuIGFjY2VudCwgCgkgKiBvciB0aGUgY3VycmVudCBvZmZzZXQgaWYgdGhlIGN1cnJlbnQgY2hhcmFjdGVyIGNvbnRhaW5zIGEgYmFzZSBjaGFyYWN0ZXIuIAoJICogYWNjZW50cyB0aGUgZm9sbG93aW5nIGJhc2UgY2hhcmFjdGVyIHdpbGwgYmUgcmV0dXJuZWQKCSAqIEBwYXJhbSB0ZXh0IHN0cmluZwoJICogQHBhcmFtIHRleHRvZmZzZXQgY3VycmVudCBvZmZzZXQKCSAqIEBwYXJhbSB0ZXh0bGVuZ3RoIGxlbmd0aCBvZiB0ZXh0IHN0cmluZwoJICogQHJldHVybiB0aGUgbmV4dCBiYXNlIGNoYXJhY3RlciBvciB0aGUgY3VycmVudCBvZmZzZXQKCSAqICAgICAgICAgaWYgdGhlIGN1cnJlbnQgY2hhcmFjdGVyIGlzIGNvbnRhaW5zIGEgYmFzZSBjaGFyYWN0ZXIuCgkgKi8KCXByaXZhdGUgZmluYWwgaW50IGdldE5leHRCYXNlT2Zmc2V0KENoYXJhY3Rlckl0ZXJhdG9yIHRleHQsIAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAkJIGludCB0ZXh0b2Zmc2V0KQoJewoJICAgIGlmICh0ZXh0b2Zmc2V0IDwgdGV4dC5nZXRFbmRJbmRleCgpKSB7CgkgICAgICAgIHdoaWxlICh0ZXh0LmdldEluZGV4KCkgPCB0ZXh0LmdldEVuZEluZGV4KCkpIHsgCgkgICAgICAgICAgICBpbnQgcmVzdWx0ID0gdGV4dG9mZnNldDsKCSAgICAgICAgICAgIGlmICgoZ2V0RkNEKHRleHQsIHRleHRvZmZzZXQgKyspIAoJICAgICAgICAgICAgICAgIAkJPj4gU0VDT05EX0xBU1RfQllURV9TSElGVF8pID09IDApIHsKCSAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgICAgICByZXR1cm4gdGV4dC5nZXRFbmRJbmRleCgpOwoJICAgIH0KCSAgICByZXR1cm4gdGV4dG9mZnNldDsKCX0KCQoJLyoqCgkgKiBHZXRzIHRoZSBuZXh0IGJhc2UgY2hhcmFjdGVyIG9mZnNldCBkZXBlbmRpbmcgb24gdGhlIHN0cmluZyBzZWFyY2ggCgkgKiBwYXR0ZXJuIGRhdGEKCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IG9uZSBvZmZzZXQgYXdheSBmcm9tIHRoZSBsYXN0IGNoYXJhY3RlcgoJICogICAgICAgICAgICAgICAgICAgdG8gc2VhcmNoIGZvci4KCSAqIEByZXR1cm4gc3RhcnQgaW5kZXggb2YgdGhlIG5leHQgYmFzZSBjaGFyYWN0ZXIgb3IgdGhlIGN1cnJlbnQgb2Zmc2V0CgkgKiAgICAgICAgIGlmIHRoZSBjdXJyZW50IGNoYXJhY3RlciBpcyBjb250YWlucyBhIGJhc2UgY2hhcmFjdGVyLgoJICovCglwcml2YXRlIGZpbmFsIGludCBnZXROZXh0QmFzZU9mZnNldChpbnQgdGV4dG9mZnNldCkKCXsKCSAgICBpZiAobV9wYXR0ZXJuXy5tX2hhc1N1ZmZpeEFjY2VudHNfIAoJICAgIAkmJiB0ZXh0b2Zmc2V0IDwgbV90ZXh0TGltaXRPZmZzZXRfKSB7CiAgICAgICAgICAgIHRhcmdldFRleHQuc2V0SW5kZXgodGV4dG9mZnNldCk7CiAgICAgICAgICAgIHRhcmdldFRleHQucHJldmlvdXMoKTsKICAgICAgICAgICAgaWYgKChnZXRGQ0QodGFyZ2V0VGV4dCwgdGFyZ2V0VGV4dC5nZXRJbmRleCgpKSAmIExBU1RfQllURV9NQVNLXykgIT0gMCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGdldE5leHRCYXNlT2Zmc2V0KHRhcmdldFRleHQsIHRleHRvZmZzZXQpOwogICAgICAgICAgICB9CgkgICAgfQoJICAgIHJldHVybiB0ZXh0b2Zmc2V0OwoJfQoJCgkvKioKCSAqIFNoaWZ0aW5nIHRoZSBjb2xsYXRpb24gZWxlbWVudCBpdGVyYXRvciBwb3NpdGlvbiBmb3J3YXJkIHRvIHByZXBhcmUgZm9yCgkgKiBhIGZvbGxvd2luZyBtYXRjaC4gSWYgdGhlIGxhc3QgY2hhcmFjdGVyIGlzIGEgdW5zYWZlIGNoYXJhY3Rlciwgd2UnbGwgCgkgKiBvbmx5IHNoaWZ0IGJ5IDEgdG8gY2FwdHVyZSBjb250cmFjdGlvbnMsIG5vcm1hbGl6YXRpb24gZXRjLgoJICogSW50ZXJuYWwgbWV0aG9kLCBzdGF0dXMgYXNzdW1lZCB0byBiZSBzdWNjZXNzLgoJICogQHBhcmFtIHRleHRvZmZzZXQgc3RhcnQgdGV4dCBwb3NpdGlvbiB0byBkbyBzZWFyY2gKCSAqIEBwYXJhbSBjZSB0aGUgdGV4dCBjZSB3aGljaCBmYWlsZWQgdGhlIG1hdGNoLgoJICogQHBhcmFtIHBhdHRlcm5jZWluZGV4IGluZGV4IG9mIHRoZSBjZSB3aXRoaW4gdGhlIHBhdHRlcm4gY2UgYnVmZmVyIHdoaWNoCgkgKiAgICAgICAgZmFpbGVkIHRoZSBtYXRjaAoJICogQHJldHVybiBmaW5hbCBvZmZzZXQKCSAqLwoJcHJpdmF0ZSBpbnQgc2hpZnRGb3J3YXJkKGludCB0ZXh0b2Zmc2V0LCBpbnQgY2UsIGludCBwYXR0ZXJuY2VpbmRleCkKCQkJCQkJCQkJCgl7CgkgICAgaWYgKGNlICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKCSAgICAgICAgaW50IHNoaWZ0ID0gbV9wYXR0ZXJuXy5tX3NoaWZ0X1toYXNoKGNlKV07CgkgICAgICAgIC8vIHRoaXMgaXMgdG8gYWRqdXN0IGZvciBjaGFyYWN0ZXJzIGluIHRoZSBtaWRkbGUgb2YgdGhlIAoJICAgICAgICAvLyBzdWJzdHJpbmcgZm9yIG1hdGNoaW5nIHRoYXQgZmFpbGVkLgoJICAgICAgICBpbnQgYWRqdXN0ID0gbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyAtIHBhdHRlcm5jZWluZGV4OwoJICAgICAgICBpZiAoYWRqdXN0ID4gMSAmJiBzaGlmdCA+PSBhZGp1c3QpIHsKCSAgICAgICAgICAgIHNoaWZ0IC09IGFkanVzdCAtIDE7CgkgICAgICAgIH0KCSAgICAgICAgdGV4dG9mZnNldCArPSBzaGlmdDsKCSAgICB9CgkgICAgZWxzZSB7CgkgICAgICAgIHRleHRvZmZzZXQgKz0gbV9wYXR0ZXJuXy5tX2RlZmF1bHRTaGlmdFNpemVfOwoJICAgIH0KCSAgICAgCiAgICAgICAgdGV4dG9mZnNldCA9IGdldE5leHRCYXNlT2Zmc2V0KHRleHRvZmZzZXQpOwoJICAgIC8vIGNoZWNrIGZvciB1bnNhZmUgY2hhcmFjdGVycwoJICAgIC8vICogaWYgaXQgaXMgdGhlIHN0YXJ0IG9yIG1pZGRsZSBvZiBhIGNvbnRyYWN0aW9uOiB0byBiZSBkb25lIGFmdGVyIAoJICAgIC8vICAgYSBpbml0aWFsIG1hdGNoIGlzIGZvdW5kCgkgICAgLy8gKiB0aGFpIG9yIGxhbyBiYXNlIGNvbnNvbmFudCBjaGFyYWN0ZXI6IHNpbWlsYXIgdG8gY29udHJhY3Rpb24KCSAgICAvLyAqIGhpZ2ggc3Vycm9nYXRlIGNoYXJhY3Rlcjogc2ltaWxhciB0byBjb250cmFjdGlvbgoJICAgIC8vICogbmV4dCBjaGFyYWN0ZXIgaXMgYSBhY2NlbnQ6IHNoaWZ0IHRvIHRoZSBuZXh0IGJhc2UgY2hhcmFjdGVyCgkgICAgcmV0dXJuIHRleHRvZmZzZXQ7Cgl9CgkKCS8qKgoJICogR2V0cyB0aGUgb2Zmc2V0IHRvIHRoZSBuZXh0IHNhZmUgcG9pbnQgaW4gdGV4dC4KCSAqIGllLiBub3QgdGhlIG1pZGRsZSBvZiBhIGNvbnRyYWN0aW9uLCBzd2FwcGFibGUgY2hhcmFjdGVycyBvciAKCSAqIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVycy4KCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IG9mZnNldCBpbiBzdHJpbmcKCSAqIEBwYXJhbSBlbmQgb2Zmc2V0IGluIHN0cmluZwoJICogQHJldHVybiBvZmZzZXQgdG8gdGhlIG5leHQgc2FmZSBjaGFyYWN0ZXIKCSAqLwoJcHJpdmF0ZSBmaW5hbCBpbnQgZ2V0TmV4dFNhZmVPZmZzZXQoaW50IHRleHRvZmZzZXQsIGludCBlbmQpCgl7CgkgICAgaW50IHJlc3VsdCA9IHRleHRvZmZzZXQ7IC8vIGZpcnN0IGNvbnRyYWN0aW9uIGNoYXJhY3RlcgoJICAgIHRhcmdldFRleHQuc2V0SW5kZXgocmVzdWx0KTsKCSAgICB3aGlsZSAocmVzdWx0ICE9IGVuZCAmJiAKCSAgICAJbV9jb2xsYXRvcl8uaXNVbnNhZmUodGFyZ2V0VGV4dC5jdXJyZW50KCkpKSB7CgkgICAgICAgCXJlc3VsdCArKzsKCSAgICAgICAJdGFyZ2V0VGV4dC5zZXRJbmRleChyZXN1bHQpOwoJICAgIH0KCSAgICByZXR1cm4gcmVzdWx0OyAKCX0KCQoJLyoqIAoJICogVGhpcyBjaGVja3MgZm9yIGFjY2VudHMgaW4gdGhlIHBvdGVudGlhbCBtYXRjaCBzdGFydGVkIHdpdGggYSBjb21wb3NpdGUgCgkgKiBjaGFyYWN0ZXIuCgkgKiBUaGlzIGlzIHJlYWxseSBwYWluZnVsLi4uIHdlIGhhdmUgdG8gY2hlY2sgdGhhdCBjb21wb3NpdGUgY2hhcmFjdGVyIGRvIAoJICogbm90IGhhdmUgYW55IGV4dHJhIGFjY2VudHMuIFdlIGhhdmUgdG8gbm9ybWFsaXplIHRoZSBwb3RlbnRpYWwgbWF0Y2ggYW5kIAoJICogZmluZCB0aGUgaW1tZWRpYXRlIGRlY29tcG9zZWQgY2hhcmFjdGVyIGJlZm9yZSB0aGUgbWF0Y2guCgkgKiBUaGUgZmlyc3QgY29tcG9zaXRlIGNoYXJhY3RlciB3b3VsZCBoYXZlIGJlZW4gdGFrZW4gY2FyZSBvZiBieSB0aGUgZmNkIAoJICogY2hlY2tzIGluIGNoZWNrRm9yd2FyZEV4YWN0TWF0Y2guCgkgKiBUaGlzIGlzIHRoZSBzbG93IHBhdGggYWZ0ZXIgdGhlIGZjZCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGFuZCAKCSAqIHRoZSBsYXN0IGNoYXJhY3RlciBoYXMgYmVlbiBjaGVja2VkIGJ5IGNoZWNrRm9yd2FyZEV4YWN0TWF0Y2ggYW5kIHdlIAoJICogZGV0ZXJtaW5lIHRoYXQgdGhlIHBvdGVudGlhbCBtYXRjaCBoYXMgZXh0cmEgbm9uLWlnbm9yYWJsZSBwcmVjZWRpbmcKCSAqIGNlcy4KCSAqIEUuZy4gbG9va2luZyBmb3IgXHUwMzAxIGFjdXRlIGluIFx1MDFGQSBBIHJpbmcgYWJvdmUgYW5kIGFjdXRlLCAKCSAqIGNoZWNrRXh0cmFNYXRjaEFjY2VudCBzaG91bGQgZmFpbCBzaW5jZSB0aGVyZSBpcyBhIG1pZGRsZSByaW5nIGluIAoJICogXHUwMUZBIE5vdGUgaGVyZSB0aGF0IGFjY2VudHMgY2hlY2tpbmcgYXJlIHNsb3cgYW5kIGNhdXRpb25lZCBpbiB0aGUgQVBJIAoJICogZG9jcy4KCSAqIEludGVybmFsIG1ldGhvZCwgc3RhdHVzIGFzc3VtZWQgdG8gYmUgYSBzdWNjZXNzLCBjYWxsZXIgc2hvdWxkIGNoZWNrIAoJICogc3RhdHVzIGJlZm9yZSBjYWxsaW5nIHRoaXMgbWV0aG9kCgkgKiBAcGFyYW0gc3RhcnQgaW5kZXggb2YgdGhlIHBvdGVudGlhbCB1bmZyaWVuZGx5IGNvbXBvc2l0ZSBjaGFyYWN0ZXIKCSAqIEBwYXJhbSBlbmQgaW5kZXggb2YgdGhlIHBvdGVudGlhbCB1bmZyaWVuZGx5IGNvbXBvc2l0ZSBjaGFyYWN0ZXIKCSAqIEByZXR1cm4gdHJ1ZSBpZiB0aGVyZSBpcyBub24taWdub3JhYmxlIGFjY2VudHMgYmVmb3JlIGF0IHRoZSBiZWdpbm5pbmcKCSAqICAgICAgICAgICAgICBvZiB0aGUgbWF0Y2gsIGZhbHNlIG90aGVyd2lzZS4KCSAqLwoJcHJpdmF0ZSBmaW5hbCBib29sZWFuIGNoZWNrRXh0cmFNYXRjaEFjY2VudHMoaW50IHN0YXJ0LCBpbnQgZW5kKQoJewoJICAgIGJvb2xlYW4gcmVzdWx0ID0gZmFsc2U7CgkgICAgaWYgKG1fcGF0dGVybl8ubV9oYXNQcmVmaXhBY2NlbnRzXykgewoJICAgICAgICB0YXJnZXRUZXh0LnNldEluZGV4KHN0YXJ0KTsKCSAgICAgICAgCgkgICAgICAgIGlmIChVVEYxNi5pc0xlYWRTdXJyb2dhdGUodGFyZ2V0VGV4dC5uZXh0KCkpKSB7CgkgICAgICAgIAlpZiAoIVVURjE2LmlzVHJhaWxTdXJyb2dhdGUodGFyZ2V0VGV4dC5uZXh0KCkpKSB7CgkgICAgICAgIAkJdGFyZ2V0VGV4dC5wcmV2aW91cygpOwoJICAgICAgICAJfQoJICAgICAgICB9CgkgICAgICAgIC8vIHdlIGFyZSBvbmx5IGNvbmNlcm5lZCB3aXRoIHRoZSBmaXJzdCBjb21wb3NpdGUgY2hhcmFjdGVyCgkgICAgICAgIFN0cmluZyBzdHIgPSBnZXRTdHJpbmcodGFyZ2V0VGV4dCwgc3RhcnQsIGVuZCk7CgkgICAgICAgIGlmIChOb3JtYWxpemVyLnF1aWNrQ2hlY2soc3RyLCBOb3JtYWxpemVyLk5GRCwwKSAKCSAgICAgICAgCQkJCQkJCQkJCT09IE5vcm1hbGl6ZXIuTk8pIHsKCSAgICAgICAgICAgIGludCBzYWZlb2Zmc2V0ID0gZ2V0TmV4dFNhZmVPZmZzZXQoc3RhcnQsIGVuZCk7CgkgICAgICAgICAgICBpZiAoc2FmZW9mZnNldCAhPSBlbmQpIHsKCSAgICAgICAgICAgICAgICBzYWZlb2Zmc2V0ICsrOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgU3RyaW5nIGRlY29tcCA9IE5vcm1hbGl6ZXIuZGVjb21wb3NlKAoJICAgICAgICAgICAgCQkJCXN0ci5zdWJzdHJpbmcoMCwgc2FmZW9mZnNldCAtIHN0YXJ0KSwgZmFsc2UpOwoJICAgICAgICAgICAgbV91dGlsQ29sRUl0ZXJfLnNldFRleHQoZGVjb21wKTsKCSAgICAgICAgICAgIGludCBmaXJzdGNlID0gbV9wYXR0ZXJuXy5tX0NFX1swXTsKCSAgICAgICAgICAgIGJvb2xlYW4gaWdub3JhYmxlID0gdHJ1ZTsKCSAgICAgICAgICAgIGludCBjZSA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEU7CgkgICAgICAgICAgICBpbnQgb2Zmc2V0ID0gMDsKCSAgICAgICAgICAgIHdoaWxlIChjZSAhPSBmaXJzdGNlKSB7CgkgICAgICAgICAgICAJb2Zmc2V0ID0gbV91dGlsQ29sRUl0ZXJfLmdldE9mZnNldCgpOwoJICAgICAgICAgICAgICAgIGlmIChjZSAhPSBmaXJzdGNlIAoJICAgICAgICAgICAgICAgIAkmJiBjZSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CgkgICAgICAgICAgICAgICAgICAgIGlnbm9yYWJsZSA9IGZhbHNlOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICBjZSA9IG1fdXRpbENvbEVJdGVyXy5uZXh0KCk7CgkgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBtX3V0aWxDb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQob2Zmc2V0KTsgLy8gYmFjayB1cCAxIHRvIHRoZSAKICAgICAgICAgICAgICAgIG1fdXRpbENvbEVJdGVyXy5wcmV2aW91cygpOyAgICAgICAgICAgICAvLyByaWdodCBvZmZzZXQKICAgICAgICAgICAgICAgIG9mZnNldCA9IG1fdXRpbENvbEVJdGVyXy5nZXRPZmZzZXQoKTsKICAgICAgICAgICAgICAgIHJlc3VsdCA9ICFpZ25vcmFibGUgJiYgKFVDaGFyYWN0ZXIuZ2V0Q29tYmluaW5nQ2xhc3MoCgkgICAgICAgICAgICAJCQkJCQkJVVRGMTYuY2hhckF0KGRlY29tcCwgb2Zmc2V0KSkgIT0gMCk7CgkgICAgICAgIH0KCSAgICB9CgkKCSAgICByZXR1cm4gcmVzdWx0OwoJfQoJCgkvKioKCSogVXNlZCBieSBleGFjdCBtYXRjaGVzLCBjaGVja3MgaWYgdGhlcmUgYXJlIGFjY2VudHMgYmVmb3JlIHRoZSBtYXRjaC4gCgkqIFRoaXMgaXMgcmVhbGx5IHBhaW5mdWwuLi4gd2UgaGF2ZSB0byBjaGVjayB0aGF0IGNvbXBvc2l0ZSBjaGFyYWN0ZXJzIGF0CgkqIHRoZSBzdGFydCBvZiB0aGUgbWF0Y2hlcyBoYXZlIHRvIG5vdCBoYXZlIGFueSBleHRyYSBhY2NlbnRzLiAKCSogV2UgY2hlY2sgdGhlIEZDRCBvZiB0aGUgY2hhcmFjdGVyIGZpcnN0LCBpZiBpdCBzdGFydHMgd2l0aCBhbiBhY2NlbnQgYW5kIAoJKiB0aGUgZmlyc3QgcGF0dGVybiBjZSBkb2VzIG5vdCBtYXRjaCB0aGUgZmlyc3QgY2Ugb2YgdGhlIGNoYXJhY3Rlciwgd2UgCgkqIGJhaWwuCgkqIE90aGVyd2lzZSB3ZSB0cnkgbm9ybWFsaXppbmcgdGhlIGZpcnN0IGNvbXBvc2l0ZSAKCSogY2hhcmFjdGVyIGFuZCBmaW5kIHRoZSBpbW1lZGlhdGUgZGVjb21wb3NlZCBjaGFyYWN0ZXIgYmVmb3JlIHRoZSBtYXRjaCB0byAKCSogc2VlIGlmIGl0IGlzIGFuIG5vbi1pZ25vcmFibGUgYWNjZW50LgoJKiBOb3cgbm9ybWFsaXppbmcgdGhlIGZpcnN0IGNvbXBvc2l0ZSBjaGFyYWN0ZXIgaXMgZW5vdWdoIGJlY2F1c2Ugd2UgZW5zdXJlIAoJKiB0aGF0IHdoZW4gdGhlIG1hdGNoIGlzIHBhc3NlZCBpbiBoZXJlIHdpdGggZXh0cmEgYmVnaW5uaW5nIGNlcywgdGhlIAoJKiBmaXJzdCBvciBsYXN0IGNlIHRoYXQgbWF0Y2ggaGFzIHRvIG9jY3VyIHdpdGhpbiB0aGUgZmlyc3QgY2hhcmFjdGVyLgoJKiBFLmcuIGxvb2tpbmcgZm9yIFx1MDMwMSBhY3V0ZSBpbiBcdTAxRkEgQSByaW5nIGFib3ZlIGFuZCBhY3V0ZSwgCgkqIGNoZWNrRXh0cmFNYXRjaEFjY2VudCBzaG91bGQgZmFpbCBzaW5jZSB0aGVyZSBpcyBhIG1pZGRsZSByaW5nIGluIFx1MDFGQQoJKiBOb3RlIGhlcmUgdGhhdCBhY2NlbnRzIGNoZWNraW5nIGFyZSBzbG93IGFuZCBjYXV0aW9uZWQgaW4gdGhlIEFQSSBkb2NzLgoJKiBAcGFyYW0gc3RhcnQgb2Zmc2V0IAoJKiBAcGFyYW0gZW5kIG9mZnNldAoJKiBAcmV0dXJuIHRydWUgaWYgdGhlcmUgYXJlIGFjY2VudHMgb24gZWl0aGVyIHNpZGUgb2YgdGhlIG1hdGNoLCAKCSogICAgICAgICBmYWxzZSBvdGhlcndpc2UKCSovCglwcml2YXRlIGZpbmFsIGJvb2xlYW4gaGFzQWNjZW50c0JlZm9yZU1hdGNoKGludCBzdGFydCwgaW50IGVuZCkgCgl7CgkgICAgaWYgKG1fcGF0dGVybl8ubV9oYXNQcmVmaXhBY2NlbnRzXykgewoJICAgICAgICAvLyB3ZSBoYXZlIGJlZW4gaXRlcmF0aW5nIGZvcndhcmRzIHByZXZpb3VzbHkKCSAgICAgICAgYm9vbGVhbiBpZ25vcmFibGUgPSB0cnVlOwoJICAgICAgICBpbnQgZmlyc3RjZSA9IG1fcGF0dGVybl8ubV9DRV9bMF07CgkJCW1fY29sRUl0ZXJfLnNldEV4YWN0T2Zmc2V0KHN0YXJ0KTsKCSAgICAgICAgaW50IGNlICA9IGdldENFKG1fY29sRUl0ZXJfLm5leHQoKSk7CgkgICAgICAgIHdoaWxlIChjZSAhPSBmaXJzdGNlKSB7CgkgICAgICAgICAgICBpZiAoY2UgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgICAgIGlnbm9yYWJsZSA9IGZhbHNlOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgY2UgPSBnZXRDRShtX2NvbEVJdGVyXy5uZXh0KCkpOwoJICAgICAgICB9CgkgICAgICAgIGlmICghaWdub3JhYmxlICYmIG1fY29sRUl0ZXJfLmlzSW5CdWZmZXIoKSkgewoJICAgICAgICAgICAgLy8gd2l0aGluIG5vcm1hbGl6YXRpb24gYnVmZmVyLCBkaXNjb250aWd1b3VzIGhhbmRsZWQgaGVyZQoJICAgICAgICAgICAgcmV0dXJuIHRydWU7CgkgICAgICAgIH0KCQoJICAgICAgICAvLyB3aXRoaW4gdGV4dAoJICAgICAgICBib29sZWFuIGFjY2VudCA9IChnZXRGQ0QodGFyZ2V0VGV4dCwgc3RhcnQpID4+IFNFQ09ORF9MQVNUX0JZVEVfU0hJRlRfKQoJICAgICAgICAJCQkJCQkJCQkJCSE9IDA7IAoJICAgICAgICBpZiAoIWFjY2VudCkgewoJICAgICAgICAgICAgcmV0dXJuIGNoZWNrRXh0cmFNYXRjaEFjY2VudHMoc3RhcnQsIGVuZCk7CgkgICAgICAgIH0KCSAgICAgICAgaWYgKCFpZ25vcmFibGUpIHsKCSAgICAgICAgICAgIHJldHVybiB0cnVlOwoJICAgICAgICB9CgkgICAgICAgIGlmIChzdGFydCA+IG1fdGV4dEJlZ2luT2Zmc2V0XykgewoJICAgICAgICAJdGFyZ2V0VGV4dC5zZXRJbmRleChzdGFydCk7CgkgICAgICAgIAl0YXJnZXRUZXh0LnByZXZpb3VzKCk7CgkgICAgICAgICAgICBpZiAoKGdldEZDRCh0YXJnZXRUZXh0LCB0YXJnZXRUZXh0LmdldEluZGV4KCkpICYgTEFTVF9CWVRFX01BU0tfKSAKCSAgICAgICAgICAgIAkJCQkJCQkJCQkJCQkJIT0gMCkgewoJICAgICAgICAgICAgICAgIG1fY29sRUl0ZXJfLnNldEV4YWN0T2Zmc2V0KHN0YXJ0KTsKCSAgICAgICAgICAgICAgICBjZSA9IG1fY29sRUl0ZXJfLnByZXZpb3VzKCk7CgkgICAgICAgICAgICAgICAgaWYgKGNlICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIgCgkgICAgICAgICAgICAgICAgCSYmIGNlICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgfQoJICAKCSAgICByZXR1cm4gZmFsc2U7Cgl9CgkKCS8qKgoJICogVXNlZCBieSBleGFjdCBtYXRjaGVzLCBjaGVja3MgaWYgdGhlcmUgYXJlIGFjY2VudHMgYm91bmRpbmcgdGhlIG1hdGNoLgoJICogTm90ZSB0aGlzIGlzIHRoZSBpbml0aWFsIGJvdW5kYXJ5IGNoZWNrLiBJZiB0aGUgcG90ZW50aWFsIG1hdGNoCgkgKiBzdGFydHMgb3IgZW5kcyB3aXRoIGNvbXBvc2l0ZSBjaGFyYWN0ZXJzLCB0aGUgYWNjZW50cyBpbiB0aG9zZQoJICogY2hhcmFjdGVycyB3aWxsIGJlIGRldGVybWluZWQgbGF0ZXIuCgkgKiBOb3QgZG9pbmcgYmFja3dhcmRzIGl0ZXJhdGlvbiBoZXJlLCBzaW5jZSBkaXNjb250aWd1b3MgY29udHJhY3Rpb24gZm9yIAoJICogYmFja3dhcmRzIGNvbGxhdGlvbiBlbGVtZW50IGl0ZXJhdG9yLCB1c2UgdXAgdG9vIG1hbnkgY2hhcmFjdGVycy4KCSAqIEUuZy4gbG9va2luZyBmb3IgXHUwMzBBIHJpbmcgaW4gXHUwMUZBIEEgcmluZyBhYm92ZSBhbmQgYWN1dGUsIAoJICogc2hvdWxkIGZhaWwgc2luY2UgdGhlcmUgaXMgYSBhY3V0ZSBhdCB0aGUgZW5kIG9mIFx1MDFGQQoJICogTm90ZSBoZXJlIHRoYXQgYWNjZW50cyBjaGVja2luZyBhcmUgc2xvdyBhbmQgY2F1dGlvbmVkIGluIHRoZSBBUEkgZG9jcy4KCSAqIEBwYXJhbSBzdGFydCBvZmZzZXQgb2YgbWF0Y2gKCSAqIEBwYXJhbSBlbmQgZW5kIG9mZnNldCBvZiB0aGUgbWF0Y2gKCSAqIEByZXR1cm4gdHJ1ZSBpZiB0aGVyZSBhcmUgYWNjZW50cyBvbiBlaXRoZXIgc2lkZSBvZiB0aGUgbWF0Y2gsIAoJICogICAgICAgICBmYWxzZSBvdGhlcndpc2UKCSAqLwoJcHJpdmF0ZSBmaW5hbCBib29sZWFuIGhhc0FjY2VudHNBZnRlck1hdGNoKGludCBzdGFydCwgaW50IGVuZCkgCgl7CgkgICAgaWYgKG1fcGF0dGVybl8ubV9oYXNTdWZmaXhBY2NlbnRzXykgewoJICAgIAl0YXJnZXRUZXh0LnNldEluZGV4KGVuZCk7CgkgICAgICAgIGlmIChlbmQgPiBtX3RleHRCZWdpbk9mZnNldF8gCgkgICAgICAgIAkmJiBVVEYxNi5pc1RyYWlsU3Vycm9nYXRlKHRhcmdldFRleHQucHJldmlvdXMoKSkpIHsKCSAgICAgICAgCWlmICh0YXJnZXRUZXh0LmdldEluZGV4KCkgPiBtX3RleHRCZWdpbk9mZnNldF8gJiYKCSAgICAgICAgCQkhVVRGMTYuaXNMZWFkU3Vycm9nYXRlKHRhcmdldFRleHQucHJldmlvdXMoKSkpIHsKCSAgICAgICAgCQl0YXJnZXRUZXh0Lm5leHQoKTsKCSAgICAgICAgCX0KCSAgICAgICAgfQoJICAgICAgICBpZiAoKGdldEZDRCh0YXJnZXRUZXh0LCB0YXJnZXRUZXh0LmdldEluZGV4KCkpICYgTEFTVF9CWVRFX01BU0tfKSAhPSAwKSB7CgkgICAgICAgICAgICBpbnQgZmlyc3RjZSAgPSBtX3BhdHRlcm5fLm1fQ0VfWzBdOwoJICAgICAgICAgICAgbV9jb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQoc3RhcnQpOwoJICAgICAgICAgICAgd2hpbGUgKGdldENFKG1fY29sRUl0ZXJfLm5leHQoKSkgIT0gZmlyc3RjZSkgewoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaW50IGNvdW50ID0gMTsKCSAgICAgICAgICAgIHdoaWxlIChjb3VudCA8IG1fcGF0dGVybl8ubV9DRUxlbmd0aF8pIHsKCSAgICAgICAgICAgICAgICBpZiAoZ2V0Q0UobV9jb2xFSXRlcl8ubmV4dCgpKSAKCSAgICAgICAgICAgICAgICAJPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgICAgIAljb3VudCAtLTsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgY291bnQgKys7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpbnQgY2UgPSBnZXRDRShtX2NvbEVJdGVyXy5uZXh0KCkpOwoJICAgICAgICAgICAgaWYgKGNlICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIgCgkgICAgICAgICAgICAJCQkmJiBjZSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CgkgICAgICAgICAgICAgICAgaWYgKG1fY29sRUl0ZXJfLmdldE9mZnNldCgpIDw9IGVuZCkgewoJICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgaWYgKChnZXRGQ0QodGFyZ2V0VGV4dCwgZW5kKSA+PiBTRUNPTkRfTEFTVF9CWVRFX1NISUZUXykgCgkgICAgICAgICAgICAgICAgCSE9IDApIHsKCSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgfQoJICAgIHJldHVybiBmYWxzZTsKCX0KCQoJLyoqCgkqIENoZWNrcyBpZiB0aGUgb2Zmc2V0IHJ1bnMgb3V0IG9mIHRoZSB0ZXh0IHN0cmluZyByYW5nZQoJKiBAcGFyYW0gdGV4dHN0YXJ0IG9mZnNldCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSByYW5nZQoJKiBAcGFyYW0gdGV4dGxpbWl0IGxpbWl0IG9mZnNldCBvZiB0aGUgdGV4dCBzdHJpbmcgcmFuZ2UKCSogQHBhcmFtIG9mZnNldCB0byB0ZXN0CgkqIEByZXR1cm4gdHJ1ZSBpZiBvZmZzZXQgaXMgb3V0IG9mIGJvdW5kcywgZmFsc2Ugb3RoZXJ3aXNlCgkqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBpc091dE9mQm91bmRzKGludCB0ZXh0c3RhcnQsIGludCB0ZXh0bGltaXQsIAoJCQkJCQkJCQkJCQlpbnQgb2Zmc2V0KQoJewoJICAgIHJldHVybiBvZmZzZXQgPCB0ZXh0c3RhcnQgfHwgb2Zmc2V0ID4gdGV4dGxpbWl0OwoJfQoJCgkvKioKCSAqIENoZWNrcyBmb3IgaWRlbnRpY2FsIG1hdGNoCgkgKiBAcGFyYW0gc3Ryc3JjaCBzdHJpbmcgc2VhcmNoIGRhdGEKCSAqIEBwYXJhbSBzdGFydCBvZmZzZXQgb2YgcG9zc2libGUgbWF0Y2gKCSAqIEBwYXJhbSBlbmQgb2Zmc2V0IG9mIHBvc3NpYmxlIG1hdGNoCgkgKiBAcmV0dXJuIHRydWUgaWYgaWRlbnRpY2FsIG1hdGNoIGlzIGZvdW5kCgkgKi8KCXByaXZhdGUgZmluYWwgYm9vbGVhbiBjaGVja0lkZW50aWNhbChpbnQgc3RhcnQsIGludCBlbmQpIAoJewoJICAgIGlmIChtX2NvbGxhdG9yXy5nZXRTdHJlbmd0aCgpICE9IENvbGxhdG9yLklERU5USUNBTCkgewoJICAgICAgICByZXR1cm4gdHJ1ZTsKCSAgICB9CgkKCQlTdHJpbmcgdGV4dHN0ciA9IGdldFN0cmluZyh0YXJnZXRUZXh0LCBzdGFydCwgZW5kIC0gc3RhcnQpOwoJCWlmIChOb3JtYWxpemVyLnF1aWNrQ2hlY2sodGV4dHN0ciwgTm9ybWFsaXplci5ORkQsMCkgCgkgICAgICAgIAkJCQkJCQkJCQk9PSBOb3JtYWxpemVyLk5PKSB7CgkgICAgICAgIHRleHRzdHIgPSBOb3JtYWxpemVyLmRlY29tcG9zZSh0ZXh0c3RyLCBmYWxzZSk7CgkgICAgfQoJICAgIFN0cmluZyBwYXR0ZXJuc3RyID0gbV9wYXR0ZXJuXy50YXJnZXRUZXh0OwoJICAgIGlmIChOb3JtYWxpemVyLnF1aWNrQ2hlY2socGF0dGVybnN0ciwgTm9ybWFsaXplci5ORkQsMCkgCgkgICAgICAgIAkJCQkJCQkJCQk9PSBOb3JtYWxpemVyLk5PKSB7CgkgICAgICAgIHBhdHRlcm5zdHIgPSBOb3JtYWxpemVyLmRlY29tcG9zZShwYXR0ZXJuc3RyLCBmYWxzZSk7CgkgICAgfQoJICAgIHJldHVybiB0ZXh0c3RyLmVxdWFscyhwYXR0ZXJuc3RyKTsKCX0KCQoJLyoqCgkgKiBDaGVja3MgdG8gc2VlIGlmIHRoZSBtYXRjaCBpcyByZXBlYXRlZAoJICogQHBhcmFtIHN0YXJ0IG5ldyBtYXRjaCBzdGFydCBpbmRleAoJICogQHBhcmFtIGxpbWl0IG5ldyBtYXRjaCBsaW1pdCBpbmRleAoJICogQHJldHVybiB0cnVlIGlmIHRoZSB0aGUgbWF0Y2ggaXMgcmVwZWF0ZWQsIGZhbHNlIG90aGVyd2lzZQoJICovCglwcml2YXRlIGZpbmFsIGJvb2xlYW4gY2hlY2tSZXBlYXRlZE1hdGNoKGludCBzdGFydCwgaW50IGxpbWl0KQoJewoJICAgIGlmIChtX21hdGNoZWRJbmRleF8gPT0gRE9ORSkgewoJICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgfQogICAgICAgIGludCBlbmQgPSBsaW1pdCAtIDE7IC8vIGxhc3QgY2hhcmFjdGVyIGluIHRoZSBtYXRjaAoJICAgIGludCBsYXN0bWF0Y2hlbmQgPSBtX21hdGNoZWRJbmRleF8gKyBtYXRjaExlbmd0aCAtIDE7IAoJICAgIGlmICghaXNPdmVybGFwcGluZygpKSB7CiAgICAgICAgICAgIHJldHVybiAoc3RhcnQgPj0gbV9tYXRjaGVkSW5kZXhfICYmIHN0YXJ0IDw9IGxhc3RtYXRjaGVuZCkgCiAgICAgICAgICAgICAgICAgICAgfHwgKGVuZCA+PSBtX21hdGNoZWRJbmRleF8gJiYgZW5kIDw9IGxhc3RtYXRjaGVuZCk7CiAgICAgICAgICAgICAgICAgICAgICAKCSAgICB9CgkgICAgcmV0dXJuIHN0YXJ0ID09IG1fbWF0Y2hlZEluZGV4XzsKCX0KCQoJLyoqCgkgKiBDaGVja3MgbWF0Y2ggZm9yIGNvbnRyYWN0aW9uLiAKCSAqIElmIHRoZSBtYXRjaCBlbmRzIHdpdGggYSBwYXJ0aWFsIGNvbnRyYWN0aW9uIHdlIGZhaWwuCgkgKiBJZiB0aGUgbWF0Y2ggc3RhcnRzIHRvbyBmYXIgb2ZmIChiZWNhdXNlIG9mIGJhY2t3YXJkcyBpdGVyYXRpb24pIHdlIHRyeSAKCSAqIHRvIGNoaXAgb2ZmIHRoZSBleHRyYSBjaGFyYWN0ZXJzIGRlcGVuZGluZyBvbiB3aGV0aGVyIGEgYnJlYWtpdGVyYXRvciAKCSAqIGhhcyBiZWVuIHVzZWQuCgkgKiBUZW1wb3JhcnkgdXRpbGl0eSBidWZmZXIgdXNlZCB0byByZXR1cm4gbW9kaWZpZWQgc3RhcnQgYW5kIGVuZC4KCSAqIEBwYXJhbSBzdGFydCBvZmZzZXQgb2YgcG90ZW50aWFsIG1hdGNoLCB0byBiZSBtb2RpZmllZCBpZiBuZWNlc3NhcnkKCSAqIEBwYXJhbSBlbmQgb2Zmc2V0IG9mIHBvdGVudGlhbCBtYXRjaCwgdG8gYmUgbW9kaWZpZWQgaWYgbmVjZXNzYXJ5CgkgKiBAcmV0dXJuIHRydWUgaWYgbWF0Y2ggcGFzc2VzIHRoZSBjb250cmFjdGlvbiB0ZXN0LCBmYWxzZSBvdGhlcndpc2UuCgkgKi8KCXByaXZhdGUgZmluYWwgYm9vbGVhbiBjaGVja05leHRFeGFjdENvbnRyYWN0aW9uTWF0Y2goaW50IHN0YXJ0LCBpbnQgZW5kKSAKCXsKCSAgICAvLyBUaGlzIHBhcnQgY2hlY2tzIGlmIGVpdGhlciBlbmRzIG9mIHRoZSBtYXRjaCBjb250YWlucyBwb3RlbnRpYWwgCgkgICAgLy8gY29udHJhY3Rpb24uIElmIHNvIHdlJ2xsIGhhdmUgdG8gaXRlcmF0ZSB0aHJvdWdoIHRoZW0KCSAgICBjaGFyIGVuZGNoYXIgPSAwOwoJICAgIGlmIChlbmQgPCBtX3RleHRMaW1pdE9mZnNldF8pIHsKCSAgICAJdGFyZ2V0VGV4dC5zZXRJbmRleChlbmQpOwoJICAgIAllbmRjaGFyID0gdGFyZ2V0VGV4dC5jdXJyZW50KCk7CgkgICAgfQoJICAgIGNoYXIgcG9zdHN0YXJ0Y2hhciA9IDA7CgkgICAgaWYgKHN0YXJ0ICsgMSA8IG1fdGV4dExpbWl0T2Zmc2V0XykgewoJICAgIAl0YXJnZXRUZXh0LnNldEluZGV4KHN0YXJ0ICsgMSk7CgkgICAgCXBvc3RzdGFydGNoYXIgPSB0YXJnZXRUZXh0LmN1cnJlbnQoKTsKCSAgICB9CgkgICAgaWYgKG1fY29sbGF0b3JfLmlzVW5zYWZlKGVuZGNoYXIpIAoJICAgIAl8fCBtX2NvbGxhdG9yXy5pc1Vuc2FmZShwb3N0c3RhcnRjaGFyKSkgewoJICAgICAgICAvLyBleHBhbnNpb24gcHJlZml4LCB3aGF0J3MgbGVmdCB0byBpdGVyYXRlCgkgICAgICAgIGludCBidWZmZXJlZENFT2Zmc2V0ID0gbV9jb2xFSXRlcl8ubV9DRUJ1ZmZlck9mZnNldF87CgkgICAgICAgIGJvb2xlYW4gaGFzQnVmZmVyZWRDRSA9IGJ1ZmZlcmVkQ0VPZmZzZXQgPiAwOwoJICAgICAgICBtX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldChzdGFydCk7CgkgICAgICAgIGludCB0ZW1wID0gc3RhcnQ7CgkgICAgICAgIHdoaWxlIChidWZmZXJlZENFT2Zmc2V0ID4gMCkgewoJICAgICAgICAgICAgLy8gZ2V0dGluZyByaWQgb2YgdGhlIHJlZHVuZGFudCBjZSwgY2F1c2VkIGJ5IHNldE9mZnNldC4KCSAgICAgICAgICAgIC8vIHNpbmNlIGJhY2t3YXJkIGNvbnRyYWN0aW9uL2V4cGFuc2lvbiBtYXkgaGF2ZSBleHRyYSBjZXMgaWYgCgkgICAgICAgICAgICAvLyB3ZSBhcmUgaW4gdGhlIG5vcm1hbGl6YXRpb24gYnVmZmVyLCBoYXNBY2NlbnRzQmVmb3JlTWF0Y2ggCgkgICAgICAgICAgICAvLyB3b3VsZCBoYXZlIHRha2VuIGNhcmUgb2YgaXQuCgkgICAgICAgICAgICAvLyBFLmcuIHRoZSBjaGFyYWN0ZXIgXHUwMUZBIHdpbGwgaGF2ZSBhbiBleHBhbnNpb24gb2YgMywgYnV0IAoJICAgICAgICAgICAgLy8gaWYgd2UgYXJlIG9ubHkgbG9va2luZyBmb3IgYWN1dGUgYW5kIHJpbmcgXHUwMzBBIGFuZCBcdTAzMDEsIAoJICAgICAgICAgICAgLy8gd2UnbGwgaGF2ZSB0byBza2lwIHRoZSBmaXJzdCBjZSBpbiB0aGUgZXhwYW5zaW9uIGJ1ZmZlci4KCSAgICAgICAgICAgIG1fY29sRUl0ZXJfLm5leHQoKTsKCSAgICAgICAgICAgIGlmIChtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKSAhPSB0ZW1wKSB7CgkgICAgICAgICAgICAgICAgc3RhcnQgPSB0ZW1wOwoJICAgICAgICAgICAgICAgIHRlbXAgID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBidWZmZXJlZENFT2Zmc2V0IC0tOwoJICAgICAgICB9CgkKCSAgICAgICAgaW50IGNvdW50ID0gMDsKCSAgICAgICAgd2hpbGUgKGNvdW50IDwgbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXykgewoJICAgICAgICAgICAgaW50IGNlID0gZ2V0Q0UobV9jb2xFSXRlcl8ubmV4dCgpKTsKCSAgICAgICAgICAgIGlmIChjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CgkgICAgICAgICAgICAgICAgY29udGludWU7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAoaGFzQnVmZmVyZWRDRSAmJiBjb3VudCA9PSAwIAoJICAgICAgICAgICAgCSYmIG1fY29sRUl0ZXJfLmdldE9mZnNldCgpICE9IHRlbXApIHsKCSAgICAgICAgICAgICAgICBzdGFydCA9IHRlbXA7CgkgICAgICAgICAgICAgICAgdGVtcCAgID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAoY2UgIT0gbV9wYXR0ZXJuXy5tX0NFX1tjb3VudF0pIHsKCSAgICAgICAgICAgICAgICBlbmQgKys7CgkgICAgICAgICAgICAgICAgZW5kID0gZ2V0TmV4dEJhc2VPZmZzZXQoZW5kKTsgIAoJICAgICAgICAgICAgICAgIG1fdXRpbEJ1ZmZlcl9bMF0gPSBzdGFydDsKCSAgICAgICAgICAgICAgICBtX3V0aWxCdWZmZXJfWzFdID0gZW5kOwoJICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGNvdW50ICsrOwoJICAgICAgICB9CgkgICAgfSAKCSAgICBtX3V0aWxCdWZmZXJfWzBdID0gc3RhcnQ7CgkgICAgbV91dGlsQnVmZmVyX1sxXSA9IGVuZDsKCSAgICByZXR1cm4gdHJ1ZTsKCX0KCQoJCgkvKioKCSAqIENoZWNrcyBhbmQgc2V0cyB0aGUgbWF0Y2ggaW5mb3JtYXRpb24gaWYgZm91bmQuCgkgKiBDaGVja3MgCgkgKiA8dWw+CgkgKiA8bGk+IHRoZSBwb3RlbnRpYWwgbWF0Y2ggZG9lcyBub3QgcmVwZWF0IHRoZSBwcmV2aW91cyBtYXRjaAoJICogPGxpPiBib3VuZGFyaWVzIGFyZSBjb3JyZWN0CgkgKiA8bGk+IGV4YWN0IG1hdGNoZXMgaGFzIG5vIGV4dHJhIGFjY2VudHMKCSAqIDxsaT4gaWRlbnRpY2FsIG1hdGNoZXNiCgkgKiA8bGk+IHBvdGVudGlhbCBtYXRjaCBkb2VzIG5vdCBlbmQgaW4gdGhlIG1pZGRsZSBvZiBhIGNvbnRyYWN0aW9uCgkgKiA8L3VsPgoJICogT3RoZXJ3aXNlIHRoZSBvZmZzZXQgd2lsbCBiZSBzaGlmdGVkIHRvIHRoZSBuZXh0IGNoYXJhY3Rlci4KCSAqIFRoZSByZXN1bHQgbV9tYXRjaEluZGV4XyBhbmQgbV9tYXRjaExlbmd0aF8gd2lsbCBiZSBzZXQgdG8gdGhlIHRydW5jYXRlZAoJICogbW9yZSBmaXR0aW5nIHJlc3VsdCB2YWx1ZS4KCSAqIFVzZXMgdGhlIHRlbXBvcmFyeSB1dGlsaXR5IGJ1ZmZlciBmb3Igc3RvcmluZyB0aGUgbW9kaWZpZWQgdGV4dG9mZnNldC4KCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IG9mZnNldCBpbiB0aGUgY29sbGF0aW9uIGVsZW1lbnQgdGV4dC4KCSAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbWF0Y2ggaXMgdmFsaWQsIGZhbHNlIG90aGVyd2lzZQoJICovCglwcml2YXRlIGZpbmFsIGJvb2xlYW4gY2hlY2tOZXh0RXhhY3RNYXRjaChpbnQgdGV4dG9mZnNldCkKCXsKCSAgICBpbnQgc3RhcnQgPSBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKTsgICAgICAgIAoJICAgIGlmICghY2hlY2tOZXh0RXhhY3RDb250cmFjdGlvbk1hdGNoKHN0YXJ0LCB0ZXh0b2Zmc2V0KSkgewoJICAgIAkvLyByZXR1cm5zIHRoZSBtb2RpZmllZCB0ZXh0b2Zmc2V0CgkgICAgCW1fdXRpbEJ1ZmZlcl9bMF0gPSBtX3V0aWxCdWZmZXJfWzFdOwoJICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgfQoJCgkJc3RhcnQgPSBtX3V0aWxCdWZmZXJfWzBdOwoJCXRleHRvZmZzZXQgPSBtX3V0aWxCdWZmZXJfWzFdOwoJICAgIC8vIHRoaXMgdG90YWxseSBtYXRjaGVzLCBob3dldmVyIHdlIG5lZWQgdG8gY2hlY2sgaWYgaXQgaXMgcmVwZWF0aW5nCgkgICAgaWYgKCFpc0JyZWFrVW5pdChzdGFydCwgdGV4dG9mZnNldCkgCgkgICAgCXx8IGNoZWNrUmVwZWF0ZWRNYXRjaChzdGFydCwgdGV4dG9mZnNldCkgCgkgICAgCXx8IGhhc0FjY2VudHNCZWZvcmVNYXRjaChzdGFydCwgdGV4dG9mZnNldCkgCgkgICAgCXx8ICFjaGVja0lkZW50aWNhbChzdGFydCwgdGV4dG9mZnNldCkgCgkgICAgCXx8IGhhc0FjY2VudHNBZnRlck1hdGNoKHN0YXJ0LCB0ZXh0b2Zmc2V0KSkgewoJICAgICAgICB0ZXh0b2Zmc2V0ICsrOwoJICAgICAgICB0ZXh0b2Zmc2V0ID0gZ2V0TmV4dEJhc2VPZmZzZXQodGV4dG9mZnNldCk7ICAKCSAgICAgICAgbV91dGlsQnVmZmVyX1swXSA9IHRleHRvZmZzZXQ7CgkgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICB9CgkgICAgICAgIAoJICAgIC8vIHRvdGFsbHkgbWF0Y2gsIHdlIHdpbGwgZ2V0IHJpZCBvZiB0aGUgZW5kaW5nIGlnbm9yYWJsZXMuCgkgICAgbV9tYXRjaGVkSW5kZXhfICA9IHN0YXJ0OwoJICAgIG1hdGNoTGVuZ3RoID0gdGV4dG9mZnNldCAtIHN0YXJ0OwoJICAgIHJldHVybiB0cnVlOwoJfQoJCgkvKioKCSogR2V0dGluZyB0aGUgcHJldmlvdXMgYmFzZSBjaGFyYWN0ZXIgb2Zmc2V0LCBvciB0aGUgY3VycmVudCBvZmZzZXQgaWYgdGhlIAoJKiBjdXJyZW50IGNoYXJhY3RlciBpcyBhIGJhc2UgY2hhcmFjdGVyCgkqIEBwYXJhbSB0ZXh0IHRoZSBzb3VyY2UgdGV4dCB0byB3b3JrIG9uCgkqIEBwYXJhbSB0ZXh0b2Zmc2V0IG9uZSBvZmZzZXQgYWZ0ZXIgdGhlIGN1cnJlbnQgY2hhcmFjdGVyCgkqIEByZXR1cm4gdGhlIG9mZnNldCBvZiB0aGUgbmV4dCBjaGFyYWN0ZXIgYWZ0ZXIgdGhlIGJhc2UgY2hhcmFjdGVyIG9yIHRoZSAKCSogCQkJZmlyc3QgY29tcG9zZWQgY2hhcmFjdGVyIHdpdGggYWNjZW50cwoJKi8KCXByaXZhdGUgZmluYWwgaW50IGdldFByZXZpb3VzQmFzZU9mZnNldChDaGFyYWN0ZXJJdGVyYXRvciB0ZXh0LCAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdGV4dG9mZnNldCkKCXsKCSAgICBpZiAodGV4dG9mZnNldCA+IG1fdGV4dEJlZ2luT2Zmc2V0XykgewoJICAgICAgICB3aGlsZSAodHJ1ZSkgewoJICAgICAgICAgICAgaW50IHJlc3VsdCA9IHRleHRvZmZzZXQ7CgkgICAgICAgICAgICB0ZXh0LnNldEluZGV4KHJlc3VsdCk7CgkgICAgICAgICAgICBpZiAoVVRGMTYuaXNUcmFpbFN1cnJvZ2F0ZSh0ZXh0LnByZXZpb3VzKCkpKSB7CgkgICAgICAgICAgICAJaWYgKHRleHQuZ2V0SW5kZXgoKSAhPSB0ZXh0LmdldEJlZ2luSW5kZXgoKSAmJgoJICAgICAgICAgICAgCQkhVVRGMTYuaXNMZWFkU3Vycm9nYXRlKHRleHQucHJldmlvdXMoKSkpIHsKCSAgICAgICAgICAgIAkJdGV4dC5uZXh0KCk7CgkgICAgICAgICAgICAJfQoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgdGV4dG9mZnNldCA9IHRleHQuZ2V0SW5kZXgoKTsKCSAgICAgICAgICAgIGNoYXIgZmNkID0gZ2V0RkNEKHRleHQsIHRleHRvZmZzZXQpOwoJICAgICAgICAgICAgaWYgKChmY2QgPj4gU0VDT05EX0xBU1RfQllURV9TSElGVF8pID09IDApIHsKCSAgICAgICAgICAgICAgICBpZiAoKGZjZCAmIExBU1RfQllURV9NQVNLXykgIT0gMCkgewoJICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGV4dG9mZnNldDsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGlmICh0ZXh0b2Zmc2V0ID09IG1fdGV4dEJlZ2luT2Zmc2V0XykgewoJICAgICAgICAgICAgICAgIHJldHVybiBtX3RleHRCZWdpbk9mZnNldF87CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgcmV0dXJuIHRleHRvZmZzZXQ7Cgl9CgkKCS8qKgoJKiBHZXR0aW5nIHRoZSBpbmRleGVzIG9mIHRoZSBhY2NlbnRzIHRoYXQgYXJlIG5vdCBibG9ja2VkIGluIHRoZSBhcmd1bWVudAoJKiBhY2NlbnQgYXJyYXkKCSogQHBhcmFtIGFjY2VudHMgYWNjZW50cyBpbiBuZmQuCgkqIEBwYXJhbSBhY2NlbnRzaW5kZXggYXJyYXkgdG8gc3RvcmUgdGhlIGluZGV4ZXMgb2YgYWNjZW50cyBpbiBhY2NlbnRzIHRoYXQgCgkqIAkJYXJlIG5vdCBibG9ja2VkCgkqIEByZXR1cm4gdGhlIGxlbmd0aCBvZiBwb3B1bGF0ZWQgYWNjZW50c2luZGV4CgkqLwoJcHJpdmF0ZSBpbnQgZ2V0VW5ibG9ja2VkQWNjZW50SW5kZXgoU3RyaW5nQnVmZmVyIGFjY2VudHMsIAoJCQkJCQkJCQkJaW50IGFjY2VudHNpbmRleFtdKQoJewoJICAgIGludCBpbmRleCA9IDA7CgkgICAgaW50IGxlbmd0aCA9IGFjY2VudHMubGVuZ3RoKCk7CgkgICAgaW50IGNjbGFzcyA9IDA7CgkgICAgaW50IHJlc3VsdCA9IDA7CgkgICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSB7CgkgICAgICAgIGludCBjb2RlcG9pbnQgPSBVVEYxNi5jaGFyQXQoYWNjZW50cywgaW5kZXgpOwoJICAgICAgICBpbnQgdGVtcGNsYXNzID0gVUNoYXJhY3Rlci5nZXRDb21iaW5pbmdDbGFzcyhjb2RlcG9pbnQpOwoJICAgICAgICBpZiAodGVtcGNsYXNzICE9IGNjbGFzcykgewoJICAgICAgICAgICAgY2NsYXNzID0gdGVtcGNsYXNzOwoJICAgICAgICAgICAgYWNjZW50c2luZGV4W3Jlc3VsdF0gPSBpbmRleDsKCSAgICAgICAgICAgIHJlc3VsdCArKzsKCSAgICAgICAgfQoJICAgICAgICBpZiAoVUNoYXJhY3Rlci5pc1N1cHBsZW1lbnRhcnkoY29kZXBvaW50KSkgewoJICAgICAgICAJaW5kZXggKz0gMjsKCSAgICAgICAgfQoJICAgICAgICBlbHNlIHsKCSAgICAgICAgCWluZGV4ICsrOwoJICAgICAgICB9CgkgICAgfQoJICAgIGFjY2VudHNpbmRleFtyZXN1bHRdID0gbGVuZ3RoOwoJICAgIHJldHVybiByZXN1bHQ7Cgl9CgoJLyoqCgkgKiBBcHBlbmRzIDMgU3RyaW5nQnVmZmVyL0NoYXJhY3Rlckl0ZXJhdG9yIHRvZ2V0aGVyIGludG8gYSBkZXN0aW5hdGlvbiAKCSAqIHN0cmluZyBidWZmZXIuCgkgKiBAcGFyYW0gc291cmNlMSBzdHJpbmcgYnVmZmVyCgkgKiBAcGFyYW0gc291cmNlMiBjaGFyYWN0ZXIgaXRlcmF0b3IKCSAqIEBwYXJhbSBzdGFydDIgc3RhcnQgb2YgdGhlIGNoYXJhY3RlciBpdGVyYXRvciB0byBtZXJnZQoJICogQHBhcmFtIGVuZDIgZW5kIG9mIHRoZSBjaGFyYWN0ZXIgaXRlcmF0b3IgdG8gbWVyZ2UKCSAqIEBwYXJhbSBzb3VyY2UzIHN0cmluZyBidWZmZXIKCSAqIEByZXR1cm4gYXBwZW5kZWQgc3RyaW5nIGJ1ZmZlcgoJICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdCdWZmZXIgbWVyZ2UoU3RyaW5nQnVmZmVyIHNvdXJjZTEsIAoJCQkJCQkJCQkgCQlDaGFyYWN0ZXJJdGVyYXRvciBzb3VyY2UyLAoJCQkJCQkJCQkgCQlpbnQgc3RhcnQyLCBpbnQgZW5kMiwKCQkJCQkJCQkJIAkJU3RyaW5nQnVmZmVyIHNvdXJjZTMpIAoJewoJCVN0cmluZ0J1ZmZlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CQoJCWlmIChzb3VyY2UxICE9IG51bGwgJiYgc291cmNlMS5sZW5ndGgoKSAhPSAwKSB7CiAgICAgICAgICAgIC8vIGpkayAxLjMuMSBkb2VzIG5vdCBoYXZlIGFwcGVuZChTdHJpbmdCdWZmZXIpIHlldAogICAgICAgICAgICBpZihjb20uaWJtLmljdS5pbXBsLklDVURlYnVnLmlzSkRLMTRPckhpZ2hlcil7CiAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHNvdXJjZTEpOwogICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoc291cmNlMS50b1N0cmluZygpKTsKICAgICAgICAgICAgfQoJCX0KCQlzb3VyY2UyLnNldEluZGV4KHN0YXJ0Mik7CgkJd2hpbGUgKHNvdXJjZTIuZ2V0SW5kZXgoKSA8IGVuZDIpIHsKCQkJcmVzdWx0LmFwcGVuZChzb3VyY2UyLmN1cnJlbnQoKSk7CgkJCXNvdXJjZTIubmV4dCgpOwoJCX0KCQlpZiAoc291cmNlMyAhPSBudWxsICYmIHNvdXJjZTMubGVuZ3RoKCkgIT0gMCkgewoJCQkvLyBqZGsgMS4zLjEgZG9lcyBub3QgaGF2ZSBhcHBlbmQoU3RyaW5nQnVmZmVyKSB5ZXQKICAgICAgICAgICAgaWYoY29tLmlibS5pY3UuaW1wbC5JQ1VEZWJ1Zy5pc0pESzE0T3JIaWdoZXIpewogICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChzb3VyY2UzKTsKICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHNvdXJjZTMudG9TdHJpbmcoKSk7CiAgICAgICAgICAgIH0KCQl9CgkgICAgcmV0dXJuIHJlc3VsdDsKCX0KCQoJLyoqCgkqIFJ1bm5pbmcgdGhyb3VnaCBhIGNvbGxhdGlvbiBlbGVtZW50IGl0ZXJhdG9yIHRvIHNlZSBpZiB0aGUgY29udGVudHMgCgkqIG1hdGNoZXMgcGF0dGVybiBpbiBzdHJpbmcgc2VhcmNoIGRhdGEKCSogQHBhcmFtIGNvbGVpdGVyIGNvbGxhdGlvbiBlbGVtZW50IGl0ZXJhdG9yIHRvIHRlc3QKCSogQHJldHVybiB0cnVlIGlmIGEgbWF0Y2ggaWYgZm91bmQsIGZhbHNlIG90aGVyd2lzZQoJKi8KCXByaXZhdGUgZmluYWwgYm9vbGVhbiBjaGVja0NvbGxhdGlvbk1hdGNoKENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBjb2xlaXRlcikKCXsKCSAgICBpbnQgcGF0dGVybmNlaW5kZXggPSBtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfOwoJICAgIGludCBvZmZzZXQgPSAwOwoJICAgIHdoaWxlIChwYXR0ZXJuY2VpbmRleCA+IDApIHsKCSAgICAgICAgaW50IGNlID0gZ2V0Q0UoY29sZWl0ZXIubmV4dCgpKTsKCSAgICAgICAgaWYgKGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICB9CgkgICAgICAgIGlmIChjZSAhPSBtX3BhdHRlcm5fLm1fQ0VfW29mZnNldF0pIHsKCSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICAgICAgfQoJICAgICAgICBvZmZzZXQgKys7CgkgICAgICAgIHBhdHRlcm5jZWluZGV4IC0tOwoJICAgIH0KCSAgICByZXR1cm4gdHJ1ZTsKCX0KCQoJLyoqCgkgKiBSZWFycmFuZ2VzIHRoZSBmcm9udCBhY2NlbnRzIHRvIHRyeSBtYXRjaGluZy4KCSAqIFByZWZpeCBhY2NlbnRzIGluIHRoZSB0ZXh0IHdpbGwgYmUgZ3JvdXBlZCBhY2NvcmRpbmcgdG8gdGhlaXIgY29tYmluaW5nIAoJICogY2xhc3MgYW5kIHRoZSBncm91cHMgd2lsbCBiZSBtaXhlZCBhbmQgbWF0Y2hlZCB0byB0cnkgZmluZCB0aGUgcGVyZmVjdCAKCSAqIG1hdGNoIHdpdGggdGhlIHBhdHRlcm4uCgkgKiBTbyBmb3IgaW5zdGFuY2UgbG9va2luZyBmb3IgIlx1MDMwMSIgaW4gIlx1MDMwQVx1MDMwMVx1MDMyNSIKCSAqIHN0ZXAgMTogc3BsaXQgIlx1MDMwQVx1MDMwMSIgaW50byA2IG90aGVyIHR5cGUgb2YgcG90ZW50aWFsIGFjY2VudCAKCSAqIAkJICAgc3Vic3RyaW5ncyAiXHUwMzBBIiwgIlx1MDMwMSIsICJcdTAzMjUiLCAiXHUwMzBBXHUwMzAxIiwgCgkgKiAJCSAgICJcdTAzMEFcdTAzMjUiLCAiXHUwMzAxXHUwMzI1Ii4KCSAqIHN0ZXAgMjogY2hlY2sgaWYgYW55IG9mIHRoZSBnZW5lcmF0ZWQgc3Vic3RyaW5ncyBtYXRjaGVzIHRoZSBwYXR0ZXJuLgoJICogSW50ZXJuYWwgbWV0aG9kLCBzdGF0dXMgaXMgYXNzdW1lZCB0byBiZSBzdWNjZXNzLCBjYWxsZXIgaGFzIHRvIGNoZWNrIAoJICogc3RhdHVzIGJlZm9yZSBjYWxsaW5nIHRoaXMgbWV0aG9kLgoJICogQHBhcmFtIHN0YXJ0IGZpcnN0IG9mZnNldCBvZiB0aGUgYWNjZW50cyB0byBzdGFydCBzZWFyY2hpbmcKCSAqIEBwYXJhbSBlbmQgc3RhcnQgb2YgdGhlIGxhc3QgYWNjZW50IHNldAoJICogQHJldHVybiBET05FIGlmIGEgbWF0Y2ggaXMgbm90IGZvdW5kLCBvdGhlcndpc2UgcmV0dXJuIHRoZSBzdGFydGluZwoJICogICAgICAgICBvZmZzZXQgb2YgdGhlIG1hdGNoLiBOb3RlIHRoaXMgc3RhcnQgaW5jbHVkZXMgYWxsIHByZWNlZGluZyAKCSAqIAkJICAgYWNjZW50cy4KCSAqLwoJcHJpdmF0ZSBpbnQgZG9OZXh0Q2Fub25pY2FsUHJlZml4TWF0Y2goaW50IHN0YXJ0LCBpbnQgZW5kKQoJewoJICAgIGlmICgoZ2V0RkNEKHRhcmdldFRleHQsIHN0YXJ0KSAmIExBU1RfQllURV9NQVNLXykgPT0gMCkgewoJICAgICAgICAvLyBkaWUuLi4gZmFpbGVkIGF0IGEgYmFzZSBjaGFyYWN0ZXIKCSAgICAgICAgcmV0dXJuIERPTkU7CgkgICAgfQoJCgkJc3RhcnQgPSB0YXJnZXRUZXh0LmdldEluZGV4KCk7IC8vIGluZGV4IGNoYW5nZWQgYnkgZmNkCgkgICAgaW50IG9mZnNldCA9IGdldE5leHRCYXNlT2Zmc2V0KHRhcmdldFRleHQsIHN0YXJ0KTsKCSAgICBzdGFydCA9IGdldFByZXZpb3VzQmFzZU9mZnNldChzdGFydCk7CgkKCSAgICBTdHJpbmdCdWZmZXIgYWNjZW50cyA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKCSAgICBTdHJpbmcgYWNjZW50c3RyID0gZ2V0U3RyaW5nKHRhcmdldFRleHQsIHN0YXJ0LCBvZmZzZXQgLSBzdGFydCk7CgkgICAgLy8gbm9ybWFsaXppbmcgdGhlIG9mZmVuc2l2ZSBzdHJpbmcKCSAgICBpZiAoTm9ybWFsaXplci5xdWlja0NoZWNrKGFjY2VudHN0ciwgTm9ybWFsaXplci5ORkQsMCkgCgkgICAgICAgIAkJCQkJCQkJCQk9PSBOb3JtYWxpemVyLk5PKSB7CgkgICAgICAgIGFjY2VudHN0ciA9IE5vcm1hbGl6ZXIuZGVjb21wb3NlKGFjY2VudHN0ciwgZmFsc2UpOwoJICAgIH0KCSAgICBhY2NlbnRzLmFwcGVuZChhY2NlbnRzdHIpOwoJICAgICAgICAKCSAgICBpbnQgYWNjZW50c2luZGV4W10gPSBuZXcgaW50W0lOSVRJQUxfQVJSQVlfU0laRV9dOyAgICAgIAoJICAgIGludCBhY2NlbnRzaXplID0gZ2V0VW5ibG9ja2VkQWNjZW50SW5kZXgoYWNjZW50cywgYWNjZW50c2luZGV4KTsKCSAgICBpbnQgY291bnQgPSAoMiA8PCAoYWNjZW50c2l6ZSAtIDEpKSAtIDI7ICAKCSAgICB3aGlsZSAoY291bnQgPiAwKSB7CgkgICAgCS8vIGNvcHkgdGhlIGJhc2UgY2hhcmFjdGVycwoJICAgIAltX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfLmRlbGV0ZSgwLCAKCSAgICAJCQkJCQkJCW1fY2Fub25pY2FsUHJlZml4QWNjZW50c18ubGVuZ3RoKCkpOwoJICAgIAlpbnQgayA9IDA7CgkgICAgICAgIGZvciAoOyBrIDwgYWNjZW50c2luZGV4WzBdOyBrICsrKSB7CgkgICAgICAgICAgICBtX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfLmFwcGVuZChhY2NlbnRzLmNoYXJBdChrKSk7CgkgICAgICAgIH0KCSAgICAgICAgLy8gZm9ybWluZyBhbGwgcG9zc2libGUgY2Fub25pY2FsIHJlYXJyYW5nZW1lbnQgYnkgZHJvcHBpbmcKCSAgICAgICAgLy8gc2V0cyBvZiBhY2NlbnRzCgkgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDw9IGFjY2VudHNpemUgLSAxOyBpICsrKSB7CgkgICAgICAgICAgICBpbnQgbWFzayA9IDEgPDwgKGFjY2VudHNpemUgLSBpIC0gMSk7CgkgICAgICAgICAgICBpZiAoKGNvdW50ICYgbWFzaykgIT0gMCkgewoJICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSBhY2NlbnRzaW5kZXhbaV07IGogPCBhY2NlbnRzaW5kZXhbaSArIDFdOyAKCSAgICAgICAgICAgICAgICAJCQkJCQkJCQkJCQkJaiArKykgewoJICAgICAgICAgICAgICAgICAgICBtX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfLmFwcGVuZChhY2NlbnRzLmNoYXJBdChqKSk7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgICAgIFN0cmluZ0J1ZmZlciBtYXRjaCA9IG1lcmdlKG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18sCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldFRleHQsIG9mZnNldCwgZW5kLAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfKTsKCSAgICAgICAgICAgIAoJICAgICAgICAvLyBpZiBzdGF0dXMgaXMgYSBmYWlsdXJlLCB1Y29sX3NldFRleHQgZG9lcyBub3RoaW5nLgoJICAgICAgICAvLyBydW4gdGhlIGNvbGxhdG9yIGl0ZXJhdG9yIHRocm91Z2ggdGhpcyBtYXRjaAoJICAgICAgICBtX3V0aWxDb2xFSXRlcl8uc2V0VGV4dChtYXRjaC50b1N0cmluZygpKTsKCSAgICAgICAgaWYgKGNoZWNrQ29sbGF0aW9uTWF0Y2gobV91dGlsQ29sRUl0ZXJfKSkgewoJICAgICAgICAgCXJldHVybiBzdGFydDsKCSAgICAgICAgfQoJICAgICAgICBjb3VudCAtLTsKCSAgICB9CgkgICAgcmV0dXJuIERPTkU7Cgl9CgoJLyoqCgkqIEdldHMgdGhlIG9mZnNldCB0byB0aGUgc2FmZSBwb2ludCBpbiB0ZXh0IGJlZm9yZSB0ZXh0b2Zmc2V0LgoJKiBpZS4gbm90IHRoZSBtaWRkbGUgb2YgYSBjb250cmFjdGlvbiwgc3dhcHBhYmxlIGNoYXJhY3RlcnMgb3IgCgkqIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVycy4KCSogQHBhcmFtIHN0YXJ0IG9mZnNldCBpbiBzdHJpbmcKCSogQHBhcmFtIHRleHRvZmZzZXQgb2Zmc2V0IGluIHN0cmluZwoJKiBAcmV0dXJuIG9mZnNldCB0byB0aGUgcHJldmlvdXMgc2FmZSBjaGFyYWN0ZXIKCSovCglwcml2YXRlIGZpbmFsIGludCBnZXRQcmV2aW91c1NhZmVPZmZzZXQoaW50IHN0YXJ0LCBpbnQgdGV4dG9mZnNldCkKCXsKCSAgICBpbnQgcmVzdWx0ID0gdGV4dG9mZnNldDsgLy8gZmlyc3QgY29udHJhY3Rpb24gY2hhcmFjdGVyCgkgICAgdGFyZ2V0VGV4dC5zZXRJbmRleCh0ZXh0b2Zmc2V0KTsKCSAgICB3aGlsZSAocmVzdWx0ID49IHN0YXJ0ICYmIG1fY29sbGF0b3JfLmlzVW5zYWZlKHRhcmdldFRleHQucHJldmlvdXMoKSkpIHsKCSAgICAgICAgcmVzdWx0ID0gdGFyZ2V0VGV4dC5nZXRJbmRleCgpOwoJICAgIH0KCSAgICBpZiAocmVzdWx0ICE9IHN0YXJ0KSB7CgkgICAgICAgIC8vIHRoZSBmaXJzdCBjb250cmFjdGlvbiBjaGFyYWN0ZXIgaXMgY29uc2lkZXIgdW5zYWZlIGhlcmUKCSAgICAgICAgcmVzdWx0ID0gdGFyZ2V0VGV4dC5nZXRJbmRleCgpOyAvLyBvcmlnaW5hbGx5IHJlc3VsdCAtLTsKCSAgICB9CgkgICAgcmV0dXJuIHJlc3VsdDsgCgl9CgoJLyoqCgkgKiBUYWtlIHRoZSByZWFycmFuZ2VkIGVuZCBhY2NlbnRzIGFuZCB0cmllcyBtYXRjaGluZy4gSWYgbWF0Y2ggZmFpbGVkIGF0CgkgKiBhIHNlcGVyYXRlIHByZWNlZGluZyBzZXQgb2YgYWNjZW50cyAoc2VwZXJhdGVkIGZyb20gdGhlIHJlYXJyYW5nZWQgb24gYnkKCSAqIGF0IGxlYXN0IGEgYmFzZSBjaGFyYWN0ZXIpIHRoZW4gd2UgcmVhcnJhbmdlIHRoZSBwcmVjZWRpbmcgYWNjZW50cyBhbmQgCgkgKiB0cmllcyBtYXRjaGluZyBhZ2Fpbi4KCSAqIFdlIGFsbG93IHNraXBwaW5nIG9mIHRoZSBlbmRzIG9mIHRoZSBhY2NlbnQgc2V0IGlmIHRoZSBjZXMgZG8gbm90IG1hdGNoLiAKCSAqIEhvd2V2ZXIgaWYgdGhlIGZhaWx1cmUgaXMgZm91bmQgYmVmb3JlIHRoZSBhY2NlbnQgc2V0LCBpdCBmYWlscy4KCSAqIEludGVybmFsIG1ldGhvZCwgc3RhdHVzIGFzc3VtZWQgdG8gYmUgc3VjY2VzcywgY2FsbGVyIGhhcyB0byBjaGVjayAKCSAqIHN0YXR1cyBiZWZvcmUgY2FsbGluZyB0aGlzIG1ldGhvZC4KCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IG9mIHRoZSBzdGFydCBvZiB0aGUgcmVhcnJhbmdlZCBhY2NlbnQKCSAqIEByZXR1cm4gRE9ORSBpZiBhIG1hdGNoIGlzIG5vdCBmb3VuZCwgb3RoZXJ3aXNlIHJldHVybiB0aGUgc3RhcnRpbmcKCSAqICAgICAgICAgb2Zmc2V0IG9mIHRoZSBtYXRjaC4gTm90ZSB0aGlzIHN0YXJ0IGluY2x1ZGVzIGFsbCBwcmVjZWRpbmcgCgkgKiAgICAgICAgIGFjY2VudHMuCgkgKi8KCXByaXZhdGUgaW50IGRvTmV4dENhbm9uaWNhbFN1ZmZpeE1hdGNoKGludCB0ZXh0b2Zmc2V0KQoJewoJICAgIGludCBzYWZlbGVuZ3RoID0gMDsKCSAgICBTdHJpbmdCdWZmZXIgc2FmZXRleHQ7CgkJaW50IHNhZmVvZmZzZXQgPSBtX3RleHRCZWdpbk9mZnNldF87IAoJCQoJICAgIGlmICh0ZXh0b2Zmc2V0ICE9IG1fdGV4dEJlZ2luT2Zmc2V0XyAKCSAgICAJJiYgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5sZW5ndGgoKSA+IDAKCSAgICAJJiYgbV9jb2xsYXRvcl8uaXNVbnNhZmUobV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5jaGFyQXQoMCkpKSB7CgkgICAgICAgIHNhZmVvZmZzZXQgICAgID0gZ2V0UHJldmlvdXNTYWZlT2Zmc2V0KG1fdGV4dEJlZ2luT2Zmc2V0XywgCgkgICAgICAgIAkJCQkJCQkJCQl0ZXh0b2Zmc2V0KTsKCSAgICAgICAgc2FmZWxlbmd0aCAgICAgPSB0ZXh0b2Zmc2V0IC0gc2FmZW9mZnNldDsKCSAgICAgICAgc2FmZXRleHQgICAgICAgPSBtZXJnZShudWxsLCB0YXJnZXRUZXh0LCBzYWZlb2Zmc2V0LCB0ZXh0b2Zmc2V0LCAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfKTsKCSAgICB9CgkgICAgZWxzZSB7CgkgICAgICAgIHNhZmV0ZXh0ID0gbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXzsKCSAgICB9CgkKCSAgICAvLyBpZiBzdGF0dXMgaXMgYSBmYWlsdXJlLCB1Y29sX3NldFRleHQgZG9lcyBub3RoaW5nCgkgICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIGNvbGVpdGVyID0gbV91dGlsQ29sRUl0ZXJfOwoJICAgIGNvbGVpdGVyLnNldFRleHQoc2FmZXRleHQudG9TdHJpbmcoKSk7CgkgICAgLy8gc3RhdHVzIGNoZWNrZWQgaW4gbG9vcCBiZWxvdwoJCgkgICAgaW50IGNlaW5kZXggPSBtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfIC0gMTsKCSAgICBib29sZWFuIGlzU2FmZSA9IHRydWU7IC8vIGluZGljYXRpb24gZmxhZyBmb3IgcG9zaXRpb24gaW4gc2FmZSB6b25lCgkgICAgCgkgICAgd2hpbGUgKGNlaW5kZXggPj0gMCkgewoJICAgICAgICBpbnQgdGV4dGNlID0gY29sZWl0ZXIucHJldmlvdXMoKTsKCSAgICAgICAgaWYgKHRleHRjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CgkgICAgICAgICAgICAvLyBjaGVjayBpZiB3ZSBoYXZlIHBhc3NlZCB0aGUgc2FmZSBidWZmZXIKCSAgICAgICAgICAgIGlmIChjb2xlaXRlciA9PSBtX2NvbEVJdGVyXykgewoJICAgICAgICAgICAgICAgIHJldHVybiBET05FOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgY29sZWl0ZXIgPSBtX2NvbEVJdGVyXzsKCSAgICAgICAgICAgIGlmIChzYWZldGV4dCAhPSBtX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfKSB7CgkgICAgICAgICAgICAJc2FmZXRleHQuZGVsZXRlKDAsIHNhZmV0ZXh0Lmxlbmd0aCgpKTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGNvbGVpdGVyLnNldEV4YWN0T2Zmc2V0KHNhZmVvZmZzZXQpOwoJICAgICAgICAgICAgLy8gc3RhdHVzIGNoZWNrZWQgYXQgdGhlIHN0YXJ0IG9mIHRoZSBsb29wCgkgICAgICAgICAgICBpc1NhZmUgPSBmYWxzZTsKCSAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICB9CgkgICAgICAgIHRleHRjZSA9IGdldENFKHRleHRjZSk7CgkgICAgICAgIGlmICh0ZXh0Y2UgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSAKCSAgICAgICAgCSYmIHRleHRjZSAhPSBtX3BhdHRlcm5fLm1fQ0VfW2NlaW5kZXhdKSB7CgkgICAgICAgICAgICAvLyBkbyB0aGUgYmVnaW5uaW5nIHN0dWZmCgkgICAgICAgICAgICBpbnQgZmFpbGVkb2Zmc2V0ID0gY29sZWl0ZXIuZ2V0T2Zmc2V0KCk7CgkgICAgICAgICAgICBpZiAoaXNTYWZlICYmIGZhaWxlZG9mZnNldCA+PSBzYWZlbGVuZ3RoKSB7CgkgICAgICAgICAgICAgICAgLy8gYWxhcy4uLiBubyBob3BlLiBmYWlsZWQgYXQgcmVhcnJhbmdlZCBhY2NlbnQgc2V0CgkgICAgICAgICAgICAgICAgcmV0dXJuIERPTkU7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBlbHNlIHsKCSAgICAgICAgICAgICAgICBpZiAoaXNTYWZlKSB7CgkgICAgICAgICAgICAgICAgICAgIGZhaWxlZG9mZnNldCArPSBzYWZlb2Zmc2V0OwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICAKCSAgICAgICAgICAgICAgICAvLyB0cnkgcmVhcnJhbmdpbmcgdGhlIGZyb250IGFjY2VudHMKCSAgICAgICAgICAgICAgICBpbnQgcmVzdWx0ID0gZG9OZXh0Q2Fub25pY2FsUHJlZml4TWF0Y2goZmFpbGVkb2Zmc2V0LCAKCSAgICAgICAgICAgICAgICAJCQkJCQkJCQkJdGV4dG9mZnNldCk7CgkgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSBET05FKSB7CgkgICAgICAgICAgICAgICAgICAgIC8vIGlmIHN0YXR1cyBpcyBhIGZhaWx1cmUsIHVjb2xfc2V0T2Zmc2V0IGRvZXMgbm90aGluZwoJICAgICAgICAgICAgICAgICAgICBtX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldChyZXN1bHQpOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgICAgIGlmICh0ZXh0Y2UgPT0gbV9wYXR0ZXJuXy5tX0NFX1tjZWluZGV4XSkgewoJICAgICAgICAgICAgY2VpbmRleCAtLTsKCSAgICAgICAgfQoJICAgIH0KCSAgICAvLyBzZXQgb2Zmc2V0IGhlcmUKCSAgICBpZiAoaXNTYWZlKSB7CgkgICAgICAgIGludCByZXN1bHQgPSBjb2xlaXRlci5nZXRPZmZzZXQoKTsKCSAgICAgICAgLy8gc2V0cyB0aGUgdGV4dCBpdGVyYXRvciB3aXRoIHRoZSBjb3JyZWN0IGV4cGFuc2lvbiBhbmQgb2Zmc2V0CgkgICAgICAgIGludCBsZWZ0b3ZlcmNlcyA9IGNvbGVpdGVyLm1fQ0VCdWZmZXJPZmZzZXRfOwoJICAgICAgICBpZiAocmVzdWx0ID49IHNhZmVsZW5ndGgpIHsgCgkgICAgICAgICAgICByZXN1bHQgPSB0ZXh0b2Zmc2V0OwoJICAgICAgICB9CgkgICAgICAgIGVsc2UgewoJICAgICAgICAgICAgcmVzdWx0ICs9IHNhZmVvZmZzZXQ7CgkgICAgICAgIH0KCSAgICAgICAgbV9jb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQocmVzdWx0KTsKCSAgICAgICAgbV9jb2xFSXRlcl8ubV9DRUJ1ZmZlck9mZnNldF8gPSBsZWZ0b3ZlcmNlczsKCSAgICAgICAgcmV0dXJuIHJlc3VsdDsKCSAgICB9CgkgICAgCgkgICAgcmV0dXJuIGNvbGVpdGVyLmdldE9mZnNldCgpOyAgICAgICAgICAgICAgCgl9CgkKCS8qKgoJICogVHJ5aW5nIG91dCB0aGUgc3Vic3RyaW5nIGFuZCBzZWVzIGlmIGl0IGNhbiBiZSBhIGNhbm9uaWNhbCBtYXRjaC4KCSAqIFRoaXMgd2lsbCB0cnkgbm9ybWFsaXppbmcgdGhlIGVuZCBhY2NlbnRzIGFuZCBhcnJhbmdpbmcgdGhlbSBpbnRvIAoJICogY2Fub25pY2FsIGVxdWl2YWxlbnRzIGFuZCBjaGVjayB0aGVpciBjb3JyZXNwb25kaW5nIGNlcyB3aXRoIHRoZSBwYXR0ZXJuIAoJICogY2UuCgkgKiBTdWZmaXggYWNjZW50cyBpbiB0aGUgdGV4dCB3aWxsIGJlIGdyb3VwZWQgYWNjb3JkaW5nIHRvIHRoZWlyIGNvbWJpbmluZyAKCSAqIGNsYXNzIGFuZCB0aGUgZ3JvdXBzIHdpbGwgYmUgbWl4ZWQgYW5kIG1hdGNoZWQgdG8gdHJ5IGZpbmQgdGhlIHBlcmZlY3QgCgkgKiBtYXRjaCB3aXRoIHRoZSBwYXR0ZXJuLgoJICogU28gZm9yIGluc3RhbmNlIGxvb2tpbmcgZm9yICJcdTAzMDEiIGluICJcdTAzMEFcdTAzMDFcdTAzMjUiCgkgKiBzdGVwIDE6IHNwbGl0ICJcdTAzMEFcdTAzMDEiIGludG8gNiBvdGhlciB0eXBlIG9mIHBvdGVudGlhbCBhY2NlbnQgCgkgKiAgICAgICAgIHN1YnN0cmluZ3MKCSAqICAgICAgICAgIlx1MDMwQSIsICJcdTAzMDEiLCAiXHUwMzI1IiwgIlx1MDMwQVx1MDMwMSIsICJcdTAzMEFcdTAzMjUiLCAKCSAqICAgICAgICAgIlx1MDMwMVx1MDMyNSIuCgkgKiBzdGVwIDI6IGNoZWNrIGlmIGFueSBvZiB0aGUgZ2VuZXJhdGVkIHN1YnN0cmluZ3MgbWF0Y2hlcyB0aGUgcGF0dGVybi4KCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IGVuZCBvZmZzZXQgaW4gdGhlIGNvbGxhdGlvbiBlbGVtZW50IHRleHQgdGhhdCBlbmRzIHdpdGggCgkgKiAgICAgICAgICAgICAgICAgICB0aGUgYWNjZW50cyB0byBiZSByZWFycmFuZ2VkCgkgKiBAcmV0dXJuIHRydWUgaWYgdGhlIG1hdGNoIGlzIHZhbGlkLCBmYWxzZSBvdGhlcndpc2UKCSAqLwoJcHJpdmF0ZSBib29sZWFuIGRvTmV4dENhbm9uaWNhbE1hdGNoKGludCB0ZXh0b2Zmc2V0KQoJewoJCWludCBvZmZzZXQgPSBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKTsKCQl0YXJnZXRUZXh0LnNldEluZGV4KHRleHRvZmZzZXQpOwoJCWlmIChVVEYxNi5pc1RyYWlsU3Vycm9nYXRlKHRhcmdldFRleHQucHJldmlvdXMoKSkgCgkJCSYmIHRhcmdldFRleHQuZ2V0SW5kZXgoKSA+IG1fdGV4dEJlZ2luT2Zmc2V0XykgeyAKCQkJaWYgKCFVVEYxNi5pc0xlYWRTdXJyb2dhdGUodGFyZ2V0VGV4dC5wcmV2aW91cygpKSkgewoJCQkJdGFyZ2V0VGV4dC5uZXh0KCk7CgkJCX0KCQl9CgkgICAgaWYgKChnZXRGQ0QodGFyZ2V0VGV4dCwgdGFyZ2V0VGV4dC5nZXRJbmRleCgpKSAmIExBU1RfQllURV9NQVNLXykgPT0gMCkgewoJICAgICAgICBpZiAobV9wYXR0ZXJuXy5tX2hhc1ByZWZpeEFjY2VudHNfKSB7CgkgICAgICAgICAgICBvZmZzZXQgPSBkb05leHRDYW5vbmljYWxQcmVmaXhNYXRjaChvZmZzZXQsIHRleHRvZmZzZXQpOwoJICAgICAgICAgICAgaWYgKG9mZnNldCAhPSBET05FKSB7CgkgICAgICAgICAgICAgICAgbV9jb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQob2Zmc2V0KTsKCSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgfQoJCgkgICAgaWYgKCFtX3BhdHRlcm5fLm1faGFzU3VmZml4QWNjZW50c18pIHsKCSAgICAgICAgcmV0dXJuIGZhbHNlOwoJICAgIH0KCQoJICAgIFN0cmluZ0J1ZmZlciBhY2NlbnRzID0gbmV3IFN0cmluZ0J1ZmZlcigpOwoJICAgIC8vIG9mZnNldCB0byB0aGUgbGFzdCBiYXNlIGNoYXJhY3RlciBpbiBzdWJzdHJpbmcgdG8gc2VhcmNoCgkgICAgaW50IGJhc2VvZmZzZXQgPSBnZXRQcmV2aW91c0Jhc2VPZmZzZXQodGFyZ2V0VGV4dCwgdGV4dG9mZnNldCk7CgkgICAgLy8gbm9ybWFsaXppbmcgdGhlIG9mZmVuc2l2ZSBzdHJpbmcKCSAgICBTdHJpbmcgYWNjZW50c3RyID0gZ2V0U3RyaW5nKHRhcmdldFRleHQsIGJhc2VvZmZzZXQsIAoJICAgIAkJCQkJCQkgdGV4dG9mZnNldCAtIGJhc2VvZmZzZXQpOwoJICAgIGlmIChOb3JtYWxpemVyLnF1aWNrQ2hlY2soYWNjZW50c3RyLCBOb3JtYWxpemVyLk5GRCwwKSAKCSAgICAgICAgCQkJCQkJCQkJCT09IE5vcm1hbGl6ZXIuTk8pIHsKCSAgICAgICAgYWNjZW50c3RyID0gTm9ybWFsaXplci5kZWNvbXBvc2UoYWNjZW50c3RyLCBmYWxzZSk7CgkgICAgfQoJICAgIGFjY2VudHMuYXBwZW5kKGFjY2VudHN0cik7CgkgICAgLy8gc3RhdHVzIGNoZWNrZWQgaW4gbG9vcCBiZWxvdwoJICAgICAgICAKCSAgICBpbnQgYWNjZW50c2luZGV4W10gPSBuZXcgaW50W0lOSVRJQUxfQVJSQVlfU0laRV9dOwoJICAgIGludCBzaXplID0gZ2V0VW5ibG9ja2VkQWNjZW50SW5kZXgoYWNjZW50cywgYWNjZW50c2luZGV4KTsKCQoJICAgIC8vIDIgcG93ZXIgbiAtIDEgbWludXMgdGhlIGZ1bGwgc2V0IG9mIGFjY2VudHMKCSAgICBpbnQgIGNvdW50ID0gKDIgPDwgKHNpemUgLSAxKSkgLSAyOyAgCgkgICAgd2hpbGUgKGNvdW50ID4gMCkgewogICAgICAgICAgICBtX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfLmRlbGV0ZSgwLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18ubGVuZ3RoKCkpOwoJICAgICAgICAvLyBjb3B5IHRoZSBiYXNlIGNoYXJhY3RlcnMKCSAgICAgICAgZm9yIChpbnQgayA9IDA7IGsgPCBhY2NlbnRzaW5kZXhbMF07IGsgKyspIHsKCSAgICAgICAgICAgIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18uYXBwZW5kKGFjY2VudHMuY2hhckF0KGspKTsKCSAgICAgICAgfQoJICAgICAgICAvLyBmb3JtaW5nIGFsbCBwb3NzaWJsZSBjYW5vbmljYWwgcmVhcnJhbmdlbWVudCBieSBkcm9wcGluZwoJICAgICAgICAvLyBzZXRzIG9mIGFjY2VudHMKCSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc2l6ZSAtIDE7IGkgKyspIHsKCSAgICAgICAgICAgIGludCBtYXNrID0gMSA8PCAoc2l6ZSAtIGkgLSAxKTsKCSAgICAgICAgICAgIGlmICgoY291bnQgJiBtYXNrKSAhPSAwKSB7CgkgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IGFjY2VudHNpbmRleFtpXTsgaiA8IGFjY2VudHNpbmRleFtpICsgMV07IAoJICAgICAgICAgICAgICAgIAlqICsrKSB7CgkgICAgICAgICAgICAgICAgICAgIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18uYXBwZW5kKGFjY2VudHMuY2hhckF0KGopKTsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICAgICAgb2Zmc2V0ID0gZG9OZXh0Q2Fub25pY2FsU3VmZml4TWF0Y2goYmFzZW9mZnNldCk7CgkgICAgICAgIGlmIChvZmZzZXQgIT0gRE9ORSkgewoJICAgICAgICAgICAgcmV0dXJuIHRydWU7IC8vIG1hdGNoIGZvdW5kCgkgICAgICAgIH0KCSAgICAgICAgY291bnQgLS07CgkgICAgfQoJICAgIHJldHVybiBmYWxzZTsKCX0KCQoJLyoqCgkgKiBHZXRzIHRoZSBwcmV2aW91cyBiYXNlIGNoYXJhY3RlciBvZmZzZXQgZGVwZW5kaW5nIG9uIHRoZSBzdHJpbmcgc2VhcmNoIAoJICogcGF0dGVybiBkYXRhCgkgKiBAcGFyYW0gc3Ryc3JjaCBzdHJpbmcgc2VhcmNoIGRhdGEKCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IGN1cnJlbnQgb2Zmc2V0LCBjdXJyZW50IGNoYXJhY3RlcgoJICogQHJldHVybiB0aGUgb2Zmc2V0IG9mIHRoZSBuZXh0IGNoYXJhY3RlciBhZnRlciB0aGlzIGJhc2UgY2hhcmFjdGVyIG9yIAoJICogCQkJaXRzZWxmIGlmIGl0IGlzIGEgY29tcG9zZWQgY2hhcmFjdGVyIHdpdGggYWNjZW50cwoJICovCglwcml2YXRlIGZpbmFsIGludCBnZXRQcmV2aW91c0Jhc2VPZmZzZXQoaW50IHRleHRvZmZzZXQpCgl7CgkgICAgaWYgKG1fcGF0dGVybl8ubV9oYXNQcmVmaXhBY2NlbnRzXyAmJiB0ZXh0b2Zmc2V0ID4gbV90ZXh0QmVnaW5PZmZzZXRfKSB7CgkgICAgICAgIGludCBvZmZzZXQgPSB0ZXh0b2Zmc2V0OwoJICAgICAgICBpZiAoKGdldEZDRCh0YXJnZXRUZXh0LCBvZmZzZXQpID4+IFNFQ09ORF9MQVNUX0JZVEVfU0hJRlRfKSAhPSAwKSB7CgkgICAgICAgICAgICByZXR1cm4gZ2V0UHJldmlvdXNCYXNlT2Zmc2V0KHRhcmdldFRleHQsIHRleHRvZmZzZXQpOwoJICAgICAgICB9CgkgICAgfQoJICAgIHJldHVybiB0ZXh0b2Zmc2V0OwoJfQoJCgkvKioKCSAqIENoZWNrcyBtYXRjaCBmb3IgY29udHJhY3Rpb24uIAoJICogSWYgdGhlIG1hdGNoIGVuZHMgd2l0aCBhIHBhcnRpYWwgY29udHJhY3Rpb24gd2UgZmFpbC4KCSAqIElmIHRoZSBtYXRjaCBzdGFydHMgdG9vIGZhciBvZmYgKGJlY2F1c2Ugb2YgYmFja3dhcmRzIGl0ZXJhdGlvbikgd2UgdHJ5IAoJICogdG8gY2hpcCBvZmYgdGhlIGV4dHJhIGNoYXJhY3RlcnMuCgkgKiBVc2VzIHRoZSB0ZW1wb3JhcnkgdXRpbCBidWZmZXIgZm9yIHJldHVybiB2YWx1ZXMgb2YgdGhlIG1vZGlmaWVkIHN0YXJ0CgkgKiBhbmQgZW5kLgoJICogQHBhcmFtIHN0YXJ0IG9mZnNldCBvZiBwb3RlbnRpYWwgbWF0Y2gsIHRvIGJlIG1vZGlmaWVkIGlmIG5lY2Vzc2FyeQoJICogQHBhcmFtIGVuZCBvZmZzZXQgb2YgcG90ZW50aWFsIG1hdGNoLCB0byBiZSBtb2RpZmllZCBpZiBuZWNlc3NhcnkKCSAqIEByZXR1cm4gdHJ1ZSBpZiBtYXRjaCBwYXNzZXMgdGhlIGNvbnRyYWN0aW9uIHRlc3QsIGZhbHNlIG90aGVyd2lzZS4gCgkgKi8KCXByaXZhdGUgYm9vbGVhbiBjaGVja05leHRDYW5vbmljYWxDb250cmFjdGlvbk1hdGNoKGludCBzdGFydCwgaW50IGVuZCkgCgl7CgkgICAgLy8gVGhpcyBwYXJ0IGNoZWNrcyBpZiBlaXRoZXIgZW5kcyBvZiB0aGUgbWF0Y2ggY29udGFpbnMgcG90ZW50aWFsIAoJICAgIC8vIGNvbnRyYWN0aW9uLiBJZiBzbyB3ZSdsbCBoYXZlIHRvIGl0ZXJhdGUgdGhyb3VnaCB0aGVtCgkgICAgY2hhciBzY2hhciA9IDA7CgkgICAgY2hhciBlY2hhciA9IDA7CgkgICAgaWYgKGVuZCA8IG1fdGV4dExpbWl0T2Zmc2V0XykgewoJICAgIAl0YXJnZXRUZXh0LnNldEluZGV4KGVuZCk7CgkgICAgCWVjaGFyID0gdGFyZ2V0VGV4dC5jdXJyZW50KCk7CgkgICAgfQoJICAgIGlmIChzdGFydCA8IG1fdGV4dExpbWl0T2Zmc2V0XykgewoJICAgIAl0YXJnZXRUZXh0LnNldEluZGV4KHN0YXJ0ICsgMSk7CgkgICAgCXNjaGFyID0gdGFyZ2V0VGV4dC5jdXJyZW50KCk7CgkgICAgfQoJICAgIGlmIChtX2NvbGxhdG9yXy5pc1Vuc2FmZShlY2hhcikgfHwgbV9jb2xsYXRvcl8uaXNVbnNhZmUoc2NoYXIpKSB7CgkgICAgICAgIGludCBleHBhbnNpb24gID0gbV9jb2xFSXRlcl8ubV9DRUJ1ZmZlck9mZnNldF87CgkgICAgICAgIGJvb2xlYW4gaGFzRXhwYW5zaW9uID0gZXhwYW5zaW9uID4gMDsKCSAgICAgICAgbV9jb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQoc3RhcnQpOwoJICAgICAgICBpbnQgdGVtcCA9IHN0YXJ0OwoJICAgICAgICB3aGlsZSAoZXhwYW5zaW9uID4gMCkgewoJICAgICAgICAgICAgLy8gZ2V0dGluZyByaWQgb2YgdGhlIHJlZHVuZGFudCBjZSwgY2F1c2VkIGJ5IHNldE9mZnNldC4KCSAgICAgICAgICAgIC8vIHNpbmNlIGJhY2t3YXJkIGNvbnRyYWN0aW9uL2V4cGFuc2lvbiBtYXkgaGF2ZSBleHRyYSBjZXMgaWYgCgkgICAgICAgICAgICAvLyB3ZSBhcmUgaW4gdGhlIG5vcm1hbGl6YXRpb24gYnVmZmVyLCBoYXNBY2NlbnRzQmVmb3JlTWF0Y2ggCgkgICAgICAgICAgICAvLyB3b3VsZCBoYXZlIHRha2VuIGNhcmUgb2YgaXQuCgkgICAgICAgICAgICAvLyBFLmcuIHRoZSBjaGFyYWN0ZXIgXHUwMUZBIHdpbGwgaGF2ZSBhbiBleHBhbnNpb24gb2YgMywgYnV0IAoJICAgICAgICAgICAgLy8gaWYgd2UgYXJlIG9ubHkgbG9va2luZyBmb3IgYWN1dGUgYW5kIHJpbmcgXHUwMzBBIGFuZCBcdTAzMDEsIAoJICAgICAgICAgICAgLy8gd2UnbGwgaGF2ZSB0byBza2lwIHRoZSBmaXJzdCBjZSBpbiB0aGUgZXhwYW5zaW9uIGJ1ZmZlci4KCSAgICAgICAgICAgIG1fY29sRUl0ZXJfLm5leHQoKTsKCSAgICAgICAgICAgIGlmIChtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKSAhPSB0ZW1wKSB7CgkgICAgICAgICAgICAgICAgc3RhcnQgPSB0ZW1wOwoJICAgICAgICAgICAgICAgIHRlbXAgID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBleHBhbnNpb24gLS07CgkgICAgICAgIH0KCQoJICAgICAgICBpbnQgY291bnQgPSAwOwoJICAgICAgICB3aGlsZSAoY291bnQgPCBtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfKSB7CgkgICAgICAgICAgICBpbnQgY2UgPSBnZXRDRShtX2NvbEVJdGVyXy5uZXh0KCkpOwoJICAgICAgICAgICAgLy8gc3RhdHVzIGNoZWNrZWQgYmVsb3csIG5vdGUgdGhhdCBpZiBzdGF0dXMgaXMgYSBmYWlsdXJlCgkgICAgICAgICAgICAvLyB1Y29sX25leHQgcmV0dXJucyBVQ09MX05VTExPUkRFUgoJICAgICAgICAgICAgaWYgKGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGlmIChoYXNFeHBhbnNpb24gJiYgY291bnQgPT0gMCAKCSAgICAgICAgICAgIAkmJiBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKSAhPSB0ZW1wKSB7CgkgICAgICAgICAgICAgICAgc3RhcnQgPSB0ZW1wOwoJICAgICAgICAgICAgICAgIHRlbXAgPSBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKTsKCSAgICAgICAgICAgIH0KCQoJICAgICAgICAgICAgaWYgKGNvdW50ID09IDAgJiYgY2UgIT0gbV9wYXR0ZXJuXy5tX0NFX1swXSkgewoJICAgICAgICAgICAgICAgIC8vIGFjY2VudHMgbWF5IGhhdmUgZXh0cmEgc3RhcnRpbmcgY2VzLCB0aGlzIG9jY3VycyB3aGVuIGEgCgkgICAgICAgICAgICAgICAgLy8gcHVyZSBhY2NlbnQgcGF0dGVybiBpcyBtYXRjaGVkIHdpdGhvdXQgcmVhcnJhbmdlbWVudAoJICAgICAgICAgICAgICAgIC8vIHRleHQgXHUwMzI1XHUwMzAwIGFuZCBsb29raW5nIGZvciBcdTAzMDAKCSAgICAgICAgICAgICAgICBpbnQgZXhwZWN0ZWQgPSBtX3BhdHRlcm5fLm1fQ0VfWzBdOyAKCSAgICAgICAgICAgICAgICBpZiAoKGdldEZDRCh0YXJnZXRUZXh0LCBzdGFydCkgJiBMQVNUX0JZVEVfTUFTS18pICE9IDApIHsKCSAgICAgICAgICAgICAgICAgICAgY2UgPSBnZXRDRShtX2NvbEVJdGVyXy5uZXh0KCkpOwoJICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2UgIT0gZXhwZWN0ZWQgCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBjZSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSIAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCkgPD0gZW5kKSB7CgkgICAgICAgICAgICAgICAgICAgICAgICBjZSA9IGdldENFKG1fY29sRUl0ZXJfLm5leHQoKSk7CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAoY2UgIT0gbV9wYXR0ZXJuXy5tX0NFX1tjb3VudF0pIHsKCSAgICAgICAgICAgICAgICBlbmQgKys7CgkgICAgICAgICAgICAgICAgZW5kID0gZ2V0TmV4dEJhc2VPZmZzZXQoZW5kKTsgIAoJICAgICAgICAgICAgICAgIG1fdXRpbEJ1ZmZlcl9bMF0gPSBzdGFydDsKCSAgICAgICAgICAgICAgICBtX3V0aWxCdWZmZXJfWzFdID0gZW5kOwoJICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGNvdW50ICsrOwoJICAgICAgICB9CgkgICAgfSAKCSAgICBtX3V0aWxCdWZmZXJfWzBdID0gc3RhcnQ7CgkgICAgbV91dGlsQnVmZmVyX1sxXSA9IGVuZDsKCSAgICByZXR1cm4gdHJ1ZTsKCX0KCgkvKioKCSAqIENoZWNrcyBhbmQgc2V0cyB0aGUgbWF0Y2ggaW5mb3JtYXRpb24gaWYgZm91bmQuCgkgKiBDaGVja3MgCgkgKiA8dWw+CgkgKiA8bGk+IHRoZSBwb3RlbnRpYWwgbWF0Y2ggZG9lcyBub3QgcmVwZWF0IHRoZSBwcmV2aW91cyBtYXRjaAoJICogPGxpPiBib3VuZGFyaWVzIGFyZSBjb3JyZWN0CgkgKiA8bGk+IHBvdGVudGlhbCBtYXRjaCBkb2VzIG5vdCBlbmQgaW4gdGhlIG1pZGRsZSBvZiBhIGNvbnRyYWN0aW9uCgkgKiA8bGk+IGlkZW50aWNhbCBtYXRjaGVzCgkgKiA8L3VsPgoJICogT3RoZXJ3aXNlIHRoZSBvZmZzZXQgd2lsbCBiZSBzaGlmdGVkIHRvIHRoZSBuZXh0IGNoYXJhY3Rlci4KCSAqIFRoZSByZXN1bHQgbV9tYXRjaEluZGV4XyBhbmQgbV9tYXRjaExlbmd0aF8gd2lsbCBiZSBzZXQgdG8gdGhlIHRydW5jYXRlZAoJICogbW9yZSBmaXR0aW5nIHJlc3VsdCB2YWx1ZS4KCSAqIFVzZXMgdGhlIHRlbXBvcmFyeSB1dGlsaXR5IGJ1ZmZlciBmb3Igc3RvcmluZyB0aGUgbW9kaWZpZWQgdGV4dG9mZnNldC4KCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IG9mZnNldCBpbiB0aGUgY29sbGF0aW9uIGVsZW1lbnQgdGV4dC4KCSAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbWF0Y2ggaXMgdmFsaWQsIGZhbHNlIG90aGVyd2lzZQoJICovCglwcml2YXRlIGJvb2xlYW4gY2hlY2tOZXh0Q2Fub25pY2FsTWF0Y2goaW50IHRleHRvZmZzZXQpCgl7CgkgICAgLy8gdG8gZW5zdXJlIHRoYXQgdGhlIHN0YXJ0IGFuZCBlbmRzIGFyZSBub3QgY29tcG9zaXRlIGNoYXJhY3RlcnMKCSAgICAvLyBpZiB3ZSBoYXZlIGEgY2Fub25pY2FsIGFjY2VudCBtYXRjaAoJICAgIGlmICgobV9wYXR0ZXJuXy5tX2hhc1N1ZmZpeEFjY2VudHNfIAoJICAgIAkJJiYgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5sZW5ndGgoKSAhPSAwKSB8fCAKCSAgICAgICAgKG1fcGF0dGVybl8ubV9oYXNQcmVmaXhBY2NlbnRzXyAKCSAgICAgICAgCSYmIG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18ubGVuZ3RoKCkgIT0gMCkpIHsKCSAgICAgICAgbV9tYXRjaGVkSW5kZXhfID0gZ2V0UHJldmlvdXNCYXNlT2Zmc2V0KG1fY29sRUl0ZXJfLmdldE9mZnNldCgpKTsKCSAgICAgICAgbWF0Y2hMZW5ndGggPSB0ZXh0b2Zmc2V0IC0gbV9tYXRjaGVkSW5kZXhfOwoJICAgICAgICByZXR1cm4gdHJ1ZTsKCSAgICB9CgkKCSAgICBpbnQgc3RhcnQgPSBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKTsKCSAgICBpZiAoIWNoZWNrTmV4dENhbm9uaWNhbENvbnRyYWN0aW9uTWF0Y2goc3RhcnQsIHRleHRvZmZzZXQpKSB7CgkgICAgCS8vIHJldHVybiB0aGUgbW9kaWZpZWQgdGV4dG9mZnNldAoJICAgIAltX3V0aWxCdWZmZXJfWzBdID0gbV91dGlsQnVmZmVyX1sxXTsgCgkgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICB9CgkgICAgc3RhcnQgPSBtX3V0aWxCdWZmZXJfWzBdOwoJICAgIHRleHRvZmZzZXQgPSBtX3V0aWxCdWZmZXJfWzFdOwoJICAgIHN0YXJ0ID0gZ2V0UHJldmlvdXNCYXNlT2Zmc2V0KHN0YXJ0KTsKCSAgICAvLyB0aGlzIHRvdGFsbHkgbWF0Y2hlcywgaG93ZXZlciB3ZSBuZWVkIHRvIGNoZWNrIGlmIGl0IGlzIHJlcGVhdGluZwoJICAgIGlmIChjaGVja1JlcGVhdGVkTWF0Y2goc3RhcnQsIHRleHRvZmZzZXQpIAoJICAgIAl8fCAhaXNCcmVha1VuaXQoc3RhcnQsIHRleHRvZmZzZXQpIAoJICAgIAl8fCAhY2hlY2tJZGVudGljYWwoc3RhcnQsIHRleHRvZmZzZXQpKSB7CgkgICAgICAgIHRleHRvZmZzZXQgKys7CgkgICAgICAgIHRleHRvZmZzZXQgPSBnZXROZXh0QmFzZU9mZnNldCh0YXJnZXRUZXh0LCB0ZXh0b2Zmc2V0KTsKCSAgICAgICAgbV91dGlsQnVmZmVyX1swXSA9IHRleHRvZmZzZXQ7CgkgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICB9CgkgICAgCgkgICAgbV9tYXRjaGVkSW5kZXhfICA9IHN0YXJ0OwoJICAgIG1hdGNoTGVuZ3RoID0gdGV4dG9mZnNldCAtIHN0YXJ0OwoJICAgIHJldHVybiB0cnVlOwoJfQoJCgkvKioKCSAqIFNoaWZ0aW5nIHRoZSBjb2xsYXRpb24gZWxlbWVudCBpdGVyYXRvciBwb3NpdGlvbiBmb3J3YXJkIHRvIHByZXBhcmUgZm9yCgkgKiBhIHByZWNlZGluZyBtYXRjaC4gSWYgdGhlIGZpcnN0IGNoYXJhY3RlciBpcyBhIHVuc2FmZSBjaGFyYWN0ZXIsIHdlJ2xsIAoJICogb25seSBzaGlmdCBieSAxIHRvIGNhcHR1cmUgY29udHJhY3Rpb25zLCBub3JtYWxpemF0aW9uIGV0Yy4KCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IHN0YXJ0IHRleHQgcG9zaXRpb24gdG8gZG8gc2VhcmNoCgkgKiBAcGFyYW0gY2UgdGhlIHRleHQgY2Ugd2hpY2ggZmFpbGVkIHRoZSBtYXRjaC4KCSAqIEBwYXJhbSBwYXR0ZXJuY2VpbmRleCBpbmRleCBvZiB0aGUgY2Ugd2l0aGluIHRoZSBwYXR0ZXJuIGNlIGJ1ZmZlciB3aGljaAoJICogICAgICAgIGZhaWxlZCB0aGUgbWF0Y2gKCSAqIEByZXR1cm4gZmluYWwgb2Zmc2V0CgkgKi8KCXByaXZhdGUgaW50IHJldmVyc2VTaGlmdChpbnQgdGV4dG9mZnNldCwgaW50IGNlLCBpbnQgcGF0dGVybmNlaW5kZXgpCgl7ICAgICAgICAgCgkgICAgaWYgKGlzT3ZlcmxhcHBpbmcoKSkgewoJICAgICAgICBpZiAodGV4dG9mZnNldCAhPSBtX3RleHRMaW1pdE9mZnNldF8pIHsKCSAgICAgICAgICAgIHRleHRvZmZzZXQgLS07CgkgICAgICAgIH0KCSAgICAgICAgZWxzZSB7CgkgICAgICAgICAgICB0ZXh0b2Zmc2V0IC09IG1fcGF0dGVybl8ubV9kZWZhdWx0U2hpZnRTaXplXzsKCSAgICAgICAgfQoJICAgIH0KCSAgICBlbHNlIHsKCSAgICAgICAgaWYgKGNlICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKCSAgICAgICAgICAgIGludCBzaGlmdCA9IG1fcGF0dGVybl8ubV9iYWNrU2hpZnRfW2hhc2goY2UpXTsKCSAgICAgICAgICAgIAoJICAgICAgICAgICAgLy8gdGhpcyBpcyB0byBhZGp1c3QgZm9yIGNoYXJhY3RlcnMgaW4gdGhlIG1pZGRsZSBvZiB0aGUgc3Vic3RyaW5nIAoJICAgICAgICAgICAgLy8gZm9yIG1hdGNoaW5nIHRoYXQgZmFpbGVkLgoJICAgICAgICAgICAgaW50IGFkanVzdCA9IHBhdHRlcm5jZWluZGV4OwoJICAgICAgICAgICAgaWYgKGFkanVzdCA+IDEgJiYgc2hpZnQgPiBhZGp1c3QpIHsKCSAgICAgICAgICAgICAgICBzaGlmdCAtPSBhZGp1c3QgLSAxOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgdGV4dG9mZnNldCAtPSBzaGlmdDsKCSAgICAgICAgfQoJICAgICAgICBlbHNlIHsKCSAgICAgICAgICAgIHRleHRvZmZzZXQgLT0gbV9wYXR0ZXJuXy5tX2RlZmF1bHRTaGlmdFNpemVfOwoJICAgICAgICB9CgkgICAgfSAgICAKICAgICAgICAKCSAgICB0ZXh0b2Zmc2V0ID0gZ2V0UHJldmlvdXNCYXNlT2Zmc2V0KHRleHRvZmZzZXQpOwoJICAgIHJldHVybiB0ZXh0b2Zmc2V0OwoJfQoKCS8qKgoJICogQ2hlY2tzIG1hdGNoIGZvciBjb250cmFjdGlvbi4gCgkgKiBJZiB0aGUgbWF0Y2ggc3RhcnRzIHdpdGggYSBwYXJ0aWFsIGNvbnRyYWN0aW9uIHdlIGZhaWwuCgkgKiBVc2VzIHRoZSB0ZW1wb3JhcnkgdXRpbGl0eSBidWZmZXIgdG8gcmV0dXJuIHRoZSBtb2RpZmllZCBzdGFydCBhbmQgZW5kLgoJICogQHBhcmFtIHN0YXJ0IG9mZnNldCBvZiBwb3RlbnRpYWwgbWF0Y2gsIHRvIGJlIG1vZGlmaWVkIGlmIG5lY2Vzc2FyeQoJICogQHBhcmFtIGVuZCBvZmZzZXQgb2YgcG90ZW50aWFsIG1hdGNoLCB0byBiZSBtb2RpZmllZCBpZiBuZWNlc3NhcnkKCSAqIEByZXR1cm4gdHJ1ZSBpZiBtYXRjaCBwYXNzZXMgdGhlIGNvbnRyYWN0aW9uIHRlc3QsIGZhbHNlIG90aGVyd2lzZS4KCSAqLwoJcHJpdmF0ZSBib29sZWFuIGNoZWNrUHJldmlvdXNFeGFjdENvbnRyYWN0aW9uTWF0Y2goaW50IHN0YXJ0LCBpbnQgZW5kKSAKCXsKCSAgICAvLyBUaGlzIHBhcnQgY2hlY2tzIGlmIGVpdGhlciBlbmRzIG9mIHRoZSBtYXRjaCBjb250YWlucyBwb3RlbnRpYWwgCgkgICAgLy8gY29udHJhY3Rpb24uIElmIHNvIHdlJ2xsIGhhdmUgdG8gaXRlcmF0ZSB0aHJvdWdoIHRoZW0KCSAgICBjaGFyIGVjaGFyID0gMDsKCSAgICBpZiAoZW5kIDwgbV90ZXh0TGltaXRPZmZzZXRfKSB7CgkgICAgCXRhcmdldFRleHQuc2V0SW5kZXgoZW5kKTsKCSAgICAJZWNoYXIgPSB0YXJnZXRUZXh0LmN1cnJlbnQoKTsKCSAgICB9CgkgICAgY2hhciBzY2hhciA9IDA7CgkgICAgaWYgKHN0YXJ0ICsgMSA8IG1fdGV4dExpbWl0T2Zmc2V0XykgewoJICAgIAl0YXJnZXRUZXh0LnNldEluZGV4KHN0YXJ0ICsgMSk7CgkgICAgCXNjaGFyID0gdGFyZ2V0VGV4dC5jdXJyZW50KCk7CgkgICAgfQoJICAgIGlmIChtX2NvbGxhdG9yXy5pc1Vuc2FmZShlY2hhcikgfHwgbV9jb2xsYXRvcl8uaXNVbnNhZmUoc2NoYXIpKSB7CgkgICAgCS8vIGV4cGFuc2lvbiBzdWZmaXgsIHdoYXQncyBsZWZ0IHRvIGl0ZXJhdGUKCSAgICAgICAgaW50IGV4cGFuc2lvbiA9IG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJTaXplXyAKCSAgICAgICAgCQkJCQkJCQktIG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJPZmZzZXRfOwoJICAgICAgICBib29sZWFuIGhhc0V4cGFuc2lvbiA9IGV4cGFuc2lvbiA+IDA7CgkgICAgICAgIG1fY29sRUl0ZXJfLnNldEV4YWN0T2Zmc2V0KGVuZCk7CgkgICAgICAgIGludCB0ZW1wID0gZW5kOwoJICAgICAgICB3aGlsZSAoZXhwYW5zaW9uID4gMCkgewoJICAgICAgICAgICAgLy8gZ2V0dGluZyByaWQgb2YgdGhlIHJlZHVuZGFudCBjZQoJICAgICAgICAgICAgLy8gc2luY2UgZm9yd2FyZCBjb250cmFjdGlvbi9leHBhbnNpb24gbWF5IGhhdmUgZXh0cmEgY2VzCgkgICAgICAgICAgICAvLyBpZiB3ZSBhcmUgaW4gdGhlIG5vcm1hbGl6YXRpb24gYnVmZmVyLCBoYXNBY2NlbnRzQmVmb3JlTWF0Y2gKCSAgICAgICAgICAgIC8vIHdvdWxkIGhhdmUgdGFrZW4gY2FyZSBvZiBpdC4KCSAgICAgICAgICAgIC8vIEUuZy4gdGhlIGNoYXJhY3RlciBcdTAxRkEgd2lsbCBoYXZlIGFuIGV4cGFuc2lvbiBvZiAzLCBidXQgaWYKCSAgICAgICAgICAgIC8vIHdlIGFyZSBvbmx5IGxvb2tpbmcgZm9yIEEgcmluZyBBXHUwMzBBLCB3ZSdsbCBoYXZlIHRvIHNraXAgdGhlIAoJICAgICAgICAgICAgLy8gbGFzdCBjZSBpbiB0aGUgZXhwYW5zaW9uIGJ1ZmZlcgoJICAgICAgICAgICAgbV9jb2xFSXRlcl8ucHJldmlvdXMoKTsKCSAgICAgICAgICAgIGlmIChtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKSAhPSB0ZW1wKSB7CgkgICAgICAgICAgICAgICAgZW5kID0gdGVtcDsKCSAgICAgICAgICAgICAgICB0ZW1wID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBleHBhbnNpb24gLS07CgkgICAgICAgIH0KCQoJICAgICAgICBpbnQgY291bnQgPSBtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfOwoJICAgICAgICB3aGlsZSAoY291bnQgPiAwKSB7CgkgICAgICAgICAgICBpbnQgY2UgPSBnZXRDRShtX2NvbEVJdGVyXy5wcmV2aW91cygpKTsKCSAgICAgICAgICAgIC8vIHN0YXR1cyBjaGVja2VkIGJlbG93LCBub3RlIHRoYXQgaWYgc3RhdHVzIGlzIGEgZmFpbHVyZQoJICAgICAgICAgICAgLy8gdWNvbF9wcmV2aW91cyByZXR1cm5zIFVDT0xfTlVMTE9SREVSCgkgICAgICAgICAgICBpZiAoY2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKGhhc0V4cGFuc2lvbiAmJiBjb3VudCA9PSAwIAoJICAgICAgICAgICAgCSYmIG1fY29sRUl0ZXJfLmdldE9mZnNldCgpICE9IHRlbXApIHsKCSAgICAgICAgICAgICAgICBlbmQgPSB0ZW1wOwoJICAgICAgICAgICAgICAgIHRlbXAgPSBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGlmIChjZSAhPSBtX3BhdHRlcm5fLm1fQ0VfW2NvdW50IC0gMV0pIHsKCSAgICAgICAgICAgICAgICBzdGFydCAtLTsKCSAgICAgICAgICAgICAgICBzdGFydCA9IGdldFByZXZpb3VzQmFzZU9mZnNldCh0YXJnZXRUZXh0LCBzdGFydCk7CgkgICAgICAgICAgICAgICAgbV91dGlsQnVmZmVyX1swXSA9IHN0YXJ0OwoJICAgICAgICAgICAgICAgIG1fdXRpbEJ1ZmZlcl9bMV0gPSBlbmQ7CgkgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgY291bnQgLS07CgkgICAgICAgIH0KCSAgICB9IAoJICAgIG1fdXRpbEJ1ZmZlcl9bMF0gPSBzdGFydDsKCSAgICBtX3V0aWxCdWZmZXJfWzFdID0gZW5kOwoJICAgIHJldHVybiB0cnVlOwoJfQoJCgkvKioKCSAqIENoZWNrcyBhbmQgc2V0cyB0aGUgbWF0Y2ggaW5mb3JtYXRpb24gaWYgZm91bmQuCgkgKiBDaGVja3MgCgkgKiA8dWw+CgkgKiA8bGk+IHRoZSBjdXJyZW50IG1hdGNoIGRvZXMgbm90IHJlcGVhdCB0aGUgbGFzdCBtYXRjaAoJICogPGxpPiBib3VuZGFyaWVzIGFyZSBjb3JyZWN0CgkgKiA8bGk+IGV4YWN0IG1hdGNoZXMgaGFzIG5vIGV4dHJhIGFjY2VudHMKCSAqIDxsaT4gaWRlbnRpY2FsIG1hdGNoZXMKCSAqIDwvdWw+CgkgKiBPdGhlcndpc2UgdGhlIG9mZnNldCB3aWxsIGJlIHNoaWZ0ZWQgdG8gdGhlIHByZWNlZGluZyBjaGFyYWN0ZXIuCgkgKiBVc2VzIHRoZSB0ZW1wb3JhcnkgdXRpbGl0eSBidWZmZXIgdG8gc3RvcmUgdGhlIG1vZGlmaWVkIHRleHRvZmZzZXQuCgkgKiBAcGFyYW0gdGV4dG9mZnNldCBvZmZzZXQgaW4gdGhlIGNvbGxhdGlvbiBlbGVtZW50IHRleHQuIHRoZSByZXR1cm5lZCB2YWx1ZQoJICogICAgICAgIHdpbGwgYmUgdGhlIHRydW5jYXRlZCBzdGFydCBvZmZzZXQgb2YgdGhlIG1hdGNoIG9yIHRoZSBuZXcgc3RhcnQgCgkgKiAgICAgICAgc2VhcmNoIG9mZnNldC4KCSAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbWF0Y2ggaXMgdmFsaWQsIGZhbHNlIG90aGVyd2lzZQoJICovCglwcml2YXRlIGZpbmFsIGJvb2xlYW4gY2hlY2tQcmV2aW91c0V4YWN0TWF0Y2goaW50IHRleHRvZmZzZXQpCgl7CgkgICAgLy8gdG8gZW5zdXJlIHRoYXQgdGhlIHN0YXJ0IGFuZCBlbmRzIGFyZSBub3QgY29tcG9zaXRlIGNoYXJhY3RlcnMKCSAgICBpbnQgZW5kID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7ICAgICAgICAKCSAgICBpZiAoIWNoZWNrUHJldmlvdXNFeGFjdENvbnRyYWN0aW9uTWF0Y2godGV4dG9mZnNldCwgZW5kKSkgewoJICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgfQoJICAgIHRleHRvZmZzZXQgPSBtX3V0aWxCdWZmZXJfWzBdOwoJICAgIGVuZCA9IG1fdXRpbEJ1ZmZlcl9bMV07CgkgICAgICAgIAoJICAgIC8vIHRoaXMgdG90YWxseSBtYXRjaGVzLCBob3dldmVyIHdlIG5lZWQgdG8gY2hlY2sgaWYgaXQgaXMgcmVwZWF0aW5nCgkgICAgLy8gdGhlIG9sZCBtYXRjaAoJICAgIGlmIChjaGVja1JlcGVhdGVkTWF0Y2godGV4dG9mZnNldCwgZW5kKSAKCSAgICAJfHwgIWlzQnJlYWtVbml0KHRleHRvZmZzZXQsIGVuZCkgCgkgICAgCXx8IGhhc0FjY2VudHNCZWZvcmVNYXRjaCh0ZXh0b2Zmc2V0LCBlbmQpIAoJICAgIAl8fCAhY2hlY2tJZGVudGljYWwodGV4dG9mZnNldCwgZW5kKSAKCSAgICAJfHwgaGFzQWNjZW50c0FmdGVyTWF0Y2godGV4dG9mZnNldCwgZW5kKSkgewoJICAgICAgICB0ZXh0b2Zmc2V0IC0tOwoJICAgICAgICB0ZXh0b2Zmc2V0ID0gZ2V0UHJldmlvdXNCYXNlT2Zmc2V0KHRhcmdldFRleHQsIHRleHRvZmZzZXQpOwoJICAgICAgICBtX3V0aWxCdWZmZXJfWzBdID0gdGV4dG9mZnNldDsKCSAgICAgICAgcmV0dXJuIGZhbHNlOwoJICAgIH0KCSAgICBtX21hdGNoZWRJbmRleF8gPSB0ZXh0b2Zmc2V0OwoJICAgIG1hdGNoTGVuZ3RoID0gZW5kIC0gdGV4dG9mZnNldDsKCSAgICByZXR1cm4gdHJ1ZTsKCX0KCgkvKioKCSAqIFJlYXJyYW5nZXMgdGhlIGVuZCBhY2NlbnRzIHRvIHRyeSBtYXRjaGluZy4KCSAqIFN1ZmZpeCBhY2NlbnRzIGluIHRoZSB0ZXh0IHdpbGwgYmUgZ3JvdXBlZCBhY2NvcmRpbmcgdG8gdGhlaXIgY29tYmluaW5nIAoJICogY2xhc3MgYW5kIHRoZSBncm91cHMgd2lsbCBiZSBtaXhlZCBhbmQgbWF0Y2hlZCB0byB0cnkgZmluZCB0aGUgcGVyZmVjdCAKCSAqIG1hdGNoIHdpdGggdGhlIHBhdHRlcm4uCgkgKiBTbyBmb3IgaW5zdGFuY2UgbG9va2luZyBmb3IgIlx1MDMwMSIgaW4gIlx1MDMwQVx1MDMwMVx1MDMyNSIKCSAqIHN0ZXAgMTogc3BsaXQgIlx1MDMwQVx1MDMwMSIgaW50byA2IG90aGVyIHR5cGUgb2YgcG90ZW50aWFsIGFjY2VudCAKCSAqIAkJCXN1YnN0cmluZ3MKCSAqICAgICAgICAgIlx1MDMwQSIsICJcdTAzMDEiLCAiXHUwMzI1IiwgIlx1MDMwQVx1MDMwMSIsICJcdTAzMEFcdTAzMjUiLCAKCSAqICAgICAgICAgIlx1MDMwMVx1MDMyNSIuCgkgKiBzdGVwIDI6IGNoZWNrIGlmIGFueSBvZiB0aGUgZ2VuZXJhdGVkIHN1YnN0cmluZ3MgbWF0Y2hlcyB0aGUgcGF0dGVybi4KCSAqIEBwYXJhbSBzdGFydCBvZmZzZXQgb2YgdGhlIGZpcnN0IGJhc2UgY2hhcmFjdGVyCgkgKiBAcGFyYW0gZW5kIHN0YXJ0IG9mIHRoZSBsYXN0IGFjY2VudCBzZXQKCSAqIEByZXR1cm4gRE9ORSBpZiBhIG1hdGNoIGlzIG5vdCBmb3VuZCwgb3RoZXJ3aXNlIHJldHVybiB0aGUgZW5kaW5nCgkgKiAgICAgICAgIG9mZnNldCBvZiB0aGUgbWF0Y2guIE5vdGUgdGhpcyBzdGFydCBpbmNsdWRlcyBhbGwgZm9sbG93aW5nIAoJICogICAgICAgICBhY2NlbnRzLgoJICovCglwcml2YXRlIGludCBkb1ByZXZpb3VzQ2Fub25pY2FsU3VmZml4TWF0Y2goaW50IHN0YXJ0LCBpbnQgZW5kKQoJewoJICAgIHRhcmdldFRleHQuc2V0SW5kZXgoZW5kKTsKCQlpZiAoVVRGMTYuaXNUcmFpbFN1cnJvZ2F0ZSh0YXJnZXRUZXh0LnByZXZpb3VzKCkpIAoJCQkmJiB0YXJnZXRUZXh0LmdldEluZGV4KCkgPiBtX3RleHRCZWdpbk9mZnNldF8pIHsKCQkJaWYgKCFVVEYxNi5pc0xlYWRTdXJyb2dhdGUodGFyZ2V0VGV4dC5wcmV2aW91cygpKSkgewoJCQkJdGFyZ2V0VGV4dC5uZXh0KCk7CgkJCX0gCgkJfQoJICAgIGlmICgoZ2V0RkNEKHRhcmdldFRleHQsIHRhcmdldFRleHQuZ2V0SW5kZXgoKSkgJiBMQVNUX0JZVEVfTUFTS18pID09IDApIHsKCSAgICAgICAgLy8gZGllLi4uIGZhaWxlZCBhdCBhIGJhc2UgY2hhcmFjdGVyCgkgICAgICAgIHJldHVybiBET05FOwoJICAgIH0KCSAgICBlbmQgPSBnZXROZXh0QmFzZU9mZnNldCh0YXJnZXRUZXh0LCBlbmQpOwoJCgkgICAgU3RyaW5nQnVmZmVyIGFjY2VudHMgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CgkgICAgaW50IG9mZnNldCA9IGdldFByZXZpb3VzQmFzZU9mZnNldCh0YXJnZXRUZXh0LCBlbmQpOwoJICAgIC8vIG5vcm1hbGl6aW5nIHRoZSBvZmZlbnNpdmUgc3RyaW5nCgkgICAgU3RyaW5nIGFjY2VudHN0ciA9IGdldFN0cmluZyh0YXJnZXRUZXh0LCBvZmZzZXQsIGVuZCAtIG9mZnNldCk7CgkgICAgaWYgKE5vcm1hbGl6ZXIucXVpY2tDaGVjayhhY2NlbnRzdHIsIE5vcm1hbGl6ZXIuTkZELDApIAoJICAgICAgICAJCQkJCQkJCQkJPT0gTm9ybWFsaXplci5OTykgewoJICAgICAgICBhY2NlbnRzdHIgPSBOb3JtYWxpemVyLmRlY29tcG9zZShhY2NlbnRzdHIsIGZhbHNlKTsKCSAgICB9CgkgICAgYWNjZW50cy5hcHBlbmQoYWNjZW50c3RyKTsgICAgCgkgICAgICAgIAoJICAgIGludCBhY2NlbnRzaW5kZXhbXSA9IG5ldyBpbnRbSU5JVElBTF9BUlJBWV9TSVpFX107ICAgICAgCgkgICAgaW50IGFjY2VudHNpemUgPSBnZXRVbmJsb2NrZWRBY2NlbnRJbmRleChhY2NlbnRzLCBhY2NlbnRzaW5kZXgpOwoJICAgIGludCBjb3VudCA9ICgyIDw8IChhY2NlbnRzaXplIC0gMSkpIC0gMjsgIAoJICAgIHdoaWxlIChjb3VudCA+IDApIHsKICAgICAgICAgICAgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5kZWxldGUoMCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfLmxlbmd0aCgpKTsKCSAgICAgICAgLy8gY29weSB0aGUgYmFzZSBjaGFyYWN0ZXJzCgkgICAgICAgIGZvciAoaW50IGsgPSAwOyBrIDwgYWNjZW50c2luZGV4WzBdOyBrICsrKSB7CgkgICAgICAgICAgICAgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5hcHBlbmQoYWNjZW50cy5jaGFyQXQoaykpOwoJICAgICAgICB9CgkgICAgICAgIC8vIGZvcm1pbmcgYWxsIHBvc3NpYmxlIGNhbm9uaWNhbCByZWFycmFuZ2VtZW50IGJ5IGRyb3BwaW5nCgkgICAgICAgIC8vIHNldHMgb2YgYWNjZW50cwoJICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8PSBhY2NlbnRzaXplIC0gMTsgaSArKykgewoJICAgICAgICAgICAgaW50IG1hc2sgPSAxIDw8IChhY2NlbnRzaXplIC0gaSAtIDEpOwoJICAgICAgICAgICAgaWYgKChjb3VudCAmIG1hc2spICE9IDApIHsKCSAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gYWNjZW50c2luZGV4W2ldOyBqIDwgYWNjZW50c2luZGV4W2kgKyAxXTsgCgkgICAgICAgICAgICAgICAgCQkJCQkJCQkJCQkJCWogKyspIHsKCSAgICAgICAgICAgICAgICAgICAgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5hcHBlbmQoYWNjZW50cy5jaGFyQXQoaikpOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgICAgICBTdHJpbmdCdWZmZXIgbWF0Y2ggPSBtZXJnZShtX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfLCB0YXJnZXRUZXh0LAoJICAgICAgICAJCQkJCQkJc3RhcnQsIG9mZnNldCwgCgkgICAgICAgIAkJCQkJCQltX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfKTsKCSAgICAgICAgLy8gcnVuIHRoZSBjb2xsYXRvciBpdGVyYXRvciB0aHJvdWdoIHRoaXMgbWF0Y2gKCSAgICAgICAgLy8gaWYgc3RhdHVzIGlzIGEgZmFpbHVyZSB1Y29sX3NldFRleHQgZG9lcyBub3RoaW5nCgkgICAgICAgIG1fdXRpbENvbEVJdGVyXy5zZXRUZXh0KG1hdGNoLnRvU3RyaW5nKCkpOwoJICAgICAgICBpZiAoY2hlY2tDb2xsYXRpb25NYXRjaChtX3V0aWxDb2xFSXRlcl8pKSB7CgkgICAgICAgICAgICByZXR1cm4gZW5kOwoJICAgICAgICB9CgkgICAgICAgIGNvdW50IC0tOwoJICAgIH0KCSAgICByZXR1cm4gRE9ORTsKCX0KCQoJLyoqCgkgKiBUYWtlIHRoZSByZWFycmFuZ2VkIHN0YXJ0IGFjY2VudHMgYW5kIHRyaWVzIG1hdGNoaW5nLiBJZiBtYXRjaCBmYWlsZWQgYXQKCSAqIGEgc2VwZXJhdGUgZm9sbG93aW5nIHNldCBvZiBhY2NlbnRzIChzZXBlcmF0ZWQgZnJvbSB0aGUgcmVhcnJhbmdlZCBvbiBieQoJICogYXQgbGVhc3QgYSBiYXNlIGNoYXJhY3RlcikgdGhlbiB3ZSByZWFycmFuZ2UgdGhlIHByZWNlZGluZyBhY2NlbnRzIGFuZCAKCSAqIHRyaWVzIG1hdGNoaW5nIGFnYWluLgoJICogV2UgYWxsb3cgc2tpcHBpbmcgb2YgdGhlIGVuZHMgb2YgdGhlIGFjY2VudCBzZXQgaWYgdGhlIGNlcyBkbyBub3QgbWF0Y2guIAoJICogSG93ZXZlciBpZiB0aGUgZmFpbHVyZSBpcyBmb3VuZCBiZWZvcmUgdGhlIGFjY2VudCBzZXQsIGl0IGZhaWxzLgoJICogSW50ZXJuYWwgbWV0aG9kLCBzdGF0dXMgYXNzdW1lZCB0byBiZSBzdWNjZXNzLCBjYWxsZXIgaGFzIHRvIGNoZWNrIAoJICogc3RhdHVzIGJlZm9yZSBjYWxsaW5nIHRoaXMgbWV0aG9kLgoJICogQHBhcmFtIHRleHRvZmZzZXQgb2YgdGhlIGVuZHMgb2YgdGhlIHJlYXJyYW5nZWQgYWNjZW50CgkgKiBAcmV0dXJuIERPTkUgaWYgYSBtYXRjaCBpcyBub3QgZm91bmQsIG90aGVyd2lzZSByZXR1cm4gdGhlIGVuZGluZyBvZmZzZXQgCgkgKiAJCQlvZiB0aGUgbWF0Y2guIE5vdGUgdGhpcyBzdGFydCBpbmNsdWRlcyBhbGwgZm9sbG93aW5nIGFjY2VudHMuCgkgKi8KCXByaXZhdGUgaW50IGRvUHJldmlvdXNDYW5vbmljYWxQcmVmaXhNYXRjaChpbnQgdGV4dG9mZnNldCkKCXsKCSAgIC8vIGludCBzYWZlbGVuZ3RoID0gMDsKCSAgICBTdHJpbmdCdWZmZXIgc2FmZXRleHQ7CgkgICAgaW50IHNhZmVvZmZzZXQgPSB0ZXh0b2Zmc2V0OwoJCgkgICAgaWYgKHRleHRvZmZzZXQgPiBtX3RleHRCZWdpbk9mZnNldF8KCSAgICAJJiYgbV9jb2xsYXRvcl8uaXNVbnNhZmUobV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5jaGFyQXQoCgkgICAgCQkJCQkJCW1fY2Fub25pY2FsUHJlZml4QWNjZW50c18ubGVuZ3RoKCkgLSAxKSkpIHsKCSAgICAgICAgc2FmZW9mZnNldCA9IGdldE5leHRTYWZlT2Zmc2V0KHRleHRvZmZzZXQsIG1fdGV4dExpbWl0T2Zmc2V0Xyk7CgkgICAgICAgIC8vc2FmZWxlbmd0aCA9IHNhZmVvZmZzZXQgLSB0ZXh0b2Zmc2V0OwoJICAgICAgICBzYWZldGV4dCA9IG1lcmdlKG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18sIHRhcmdldFRleHQsIHRleHRvZmZzZXQsIAoJICAgICAgICAJCQkJIHNhZmVvZmZzZXQsIG51bGwpOwoJICAgIH0KCSAgICBlbHNlIHsKCSAgICAgICAgc2FmZXRleHQgPSBtX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfOwoJICAgIH0KCQoJICAgIC8vIGlmIHN0YXR1cyBpcyBhIGZhaWx1cmUsIHVjb2xfc2V0VGV4dCBkb2VzIG5vdGhpbmcKCSAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgY29sZWl0ZXIgPSBtX3V0aWxDb2xFSXRlcl87CgkgICAgY29sZWl0ZXIuc2V0VGV4dChzYWZldGV4dC50b1N0cmluZygpKTsKCSAgICAvLyBzdGF0dXMgY2hlY2tlZCBpbiBsb29wIGJlbG93CgkgICAgCgkgICAgaW50IGNlaW5kZXggPSAwOwoJICAgIGJvb2xlYW4gaXNTYWZlID0gdHJ1ZTsgLy8gc2FmZSB6b25lIGluZGljYXRpb24gZmxhZyBmb3IgcG9zaXRpb24KCSAgICBpbnQgcHJlZml4bGVuZ3RoID0gbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5sZW5ndGgoKTsKCSAgICAKCSAgICB3aGlsZSAoY2VpbmRleCA8IG1fcGF0dGVybl8ubV9DRUxlbmd0aF8pIHsKCSAgICAgICAgaW50IHRleHRjZSA9IGNvbGVpdGVyLm5leHQoKTsKCSAgICAgICAgaWYgKHRleHRjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CgkgICAgICAgICAgICAvLyBjaGVjayBpZiB3ZSBoYXZlIHBhc3NlZCB0aGUgc2FmZSBidWZmZXIKCSAgICAgICAgICAgIGlmIChjb2xlaXRlciA9PSBtX2NvbEVJdGVyXykgewoJICAgICAgICAgICAgICAgIHJldHVybiBET05FOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKHNhZmV0ZXh0ICE9IG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18pIHsKCSAgICAgICAgICAgIAlzYWZldGV4dC5kZWxldGUoMCwgc2FmZXRleHQubGVuZ3RoKCkpOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgY29sZWl0ZXIgPSBtX2NvbEVJdGVyXzsKCSAgICAgICAgICAgIGNvbGVpdGVyLnNldEV4YWN0T2Zmc2V0KHNhZmVvZmZzZXQpOwoJICAgICAgICAgICAgLy8gc3RhdHVzIGNoZWNrZWQgYXQgdGhlIHN0YXJ0IG9mIHRoZSBsb29wCgkgICAgICAgICAgICBpc1NhZmUgPSBmYWxzZTsKCSAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICB9CgkgICAgICAgIHRleHRjZSA9IGdldENFKHRleHRjZSk7CgkgICAgICAgIGlmICh0ZXh0Y2UgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSAKCSAgICAgICAgCSYmIHRleHRjZSAhPSBtX3BhdHRlcm5fLm1fQ0VfW2NlaW5kZXhdKSB7CgkgICAgICAgICAgICAvLyBkbyB0aGUgYmVnaW5uaW5nIHN0dWZmCgkgICAgICAgICAgICBpbnQgZmFpbGVkb2Zmc2V0ID0gY29sZWl0ZXIuZ2V0T2Zmc2V0KCk7CgkgICAgICAgICAgICBpZiAoaXNTYWZlICYmIGZhaWxlZG9mZnNldCA8PSBwcmVmaXhsZW5ndGgpIHsKCSAgICAgICAgICAgICAgICAvLyBhbGFzLi4uIG5vIGhvcGUuIGZhaWxlZCBhdCByZWFycmFuZ2VkIGFjY2VudCBzZXQKCSAgICAgICAgICAgICAgICByZXR1cm4gRE9ORTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGVsc2UgewoJICAgICAgICAgICAgICAgIGlmIChpc1NhZmUpIHsKCSAgICAgICAgICAgICAgICAgICAgZmFpbGVkb2Zmc2V0ID0gc2FmZW9mZnNldCAtIGZhaWxlZG9mZnNldDsKCSAgICAgICAgICAgICAgICAgICAgaWYgKHNhZmV0ZXh0ICE9IG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18pIHsKCSAgICAgICAgICAgIAkJCXNhZmV0ZXh0LmRlbGV0ZSgwLCBzYWZldGV4dC5sZW5ndGgoKSk7CgkgICAgICAgICAgICAJCX0KCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgCgkgICAgICAgICAgICAgICAgLy8gdHJ5IHJlYXJyYW5naW5nIHRoZSBlbmQgYWNjZW50cwoJICAgICAgICAgICAgICAgIGludCByZXN1bHQgPSBkb1ByZXZpb3VzQ2Fub25pY2FsU3VmZml4TWF0Y2godGV4dG9mZnNldCwgCgkgICAgICAgICAgICAgICAgCQkJCQkJCQkJCQlmYWlsZWRvZmZzZXQpOwoJICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gRE9ORSkgewoJICAgICAgICAgICAgICAgICAgICAvLyBpZiBzdGF0dXMgaXMgYSBmYWlsdXJlLCB1Y29sX3NldE9mZnNldCBkb2VzIG5vdGhpbmcKCSAgICAgICAgICAgICAgICAgICAgbV9jb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQocmVzdWx0KTsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgICAgICBpZiAodGV4dGNlID09IG1fcGF0dGVybl8ubV9DRV9bY2VpbmRleF0pIHsKCSAgICAgICAgICAgIGNlaW5kZXggKys7CgkgICAgICAgIH0KCSAgICB9CgkgICAgLy8gc2V0IG9mZnNldCBoZXJlCgkgICAgaWYgKGlzU2FmZSkgewoJICAgICAgICBpbnQgcmVzdWx0ID0gY29sZWl0ZXIuZ2V0T2Zmc2V0KCk7CgkgICAgICAgIC8vIHNldHMgdGhlIHRleHQgaXRlcmF0b3IgaGVyZSB3aXRoIHRoZSBjb3JyZWN0IGV4cGFuc2lvbiBhbmQgb2Zmc2V0CgkgICAgICAgIGludCBsZWZ0b3ZlcmNlcyA9IGNvbGVpdGVyLm1fQ0VCdWZmZXJTaXplXyAKCSAgICAgICAgCQkJCQkJCQkJLSBjb2xlaXRlci5tX0NFQnVmZmVyT2Zmc2V0XzsKCSAgICAgICAgaWYgKHJlc3VsdCA8PSBwcmVmaXhsZW5ndGgpIHsgCgkgICAgICAgICAgICByZXN1bHQgPSB0ZXh0b2Zmc2V0OwoJICAgICAgICB9CgkgICAgICAgIGVsc2UgewoJICAgICAgICAgICAgcmVzdWx0ID0gdGV4dG9mZnNldCArIChzYWZlb2Zmc2V0IC0gcmVzdWx0KTsKCSAgICAgICAgfQoJICAgICAgICBtX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldChyZXN1bHQpOwoJICAgICAgICBtX2NvbEVJdGVyXy5tX0NFQnVmZmVyT2Zmc2V0XyA9IG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJTaXplXyAKCSAgICAgICAgCQkJCQkJCQkJCQkJCS0gbGVmdG92ZXJjZXM7CgkgICAgICAgIHJldHVybiByZXN1bHQ7CgkgICAgfQoJICAgIAoJICAgIHJldHVybiBjb2xlaXRlci5nZXRPZmZzZXQoKTsgICAgICAgICAgICAgIAoJfQoJCgkvKioKCSAqIFRyeWluZyBvdXQgdGhlIHN1YnN0cmluZyBhbmQgc2VlcyBpZiBpdCBjYW4gYmUgYSBjYW5vbmljYWwgbWF0Y2guCgkgKiBUaGlzIHdpbGwgdHJ5IG5vcm1hbGl6aW5nIHRoZSBzdGFydGluZyBhY2NlbnRzIGFuZCBhcnJhbmdpbmcgdGhlbSBpbnRvIAoJICogY2Fub25pY2FsIGVxdWl2YWxlbnRzIGFuZCBjaGVjayB0aGVpciBjb3JyZXNwb25kaW5nIGNlcyB3aXRoIHRoZSBwYXR0ZXJuIAoJICogY2UuCgkgKiBQcmVmaXggYWNjZW50cyBpbiB0aGUgdGV4dCB3aWxsIGJlIGdyb3VwZWQgYWNjb3JkaW5nIHRvIHRoZWlyIGNvbWJpbmluZyAKCSAqIGNsYXNzIGFuZCB0aGUgZ3JvdXBzIHdpbGwgYmUgbWl4ZWQgYW5kIG1hdGNoZWQgdG8gdHJ5IGZpbmQgdGhlIHBlcmZlY3QgCgkgKiBtYXRjaCB3aXRoIHRoZSBwYXR0ZXJuLgoJICogU28gZm9yIGluc3RhbmNlIGxvb2tpbmcgZm9yICJcdTAzMDEiIGluICJcdTAzMEFcdTAzMDFcdTAzMjUiCgkgKiBzdGVwIDE6IHNwbGl0ICJcdTAzMEFcdTAzMDEiIGludG8gNiBvdGhlciB0eXBlIG9mIHBvdGVudGlhbCBhY2NlbnQgCgkgKiAJCSAgIHN1YnN0cmluZ3MKCSAqICAgICAgICAgIlx1MDMwQSIsICJcdTAzMDEiLCAiXHUwMzI1IiwgIlx1MDMwQVx1MDMwMSIsICJcdTAzMEFcdTAzMjUiLCAKCSAqICAgICAgICAgIlx1MDMwMVx1MDMyNSIuCgkgKiBzdGVwIDI6IGNoZWNrIGlmIGFueSBvZiB0aGUgZ2VuZXJhdGVkIHN1YnN0cmluZ3MgbWF0Y2hlcyB0aGUgcGF0dGVybi4KCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IHN0YXJ0IG9mZnNldCBpbiB0aGUgY29sbGF0aW9uIGVsZW1lbnQgdGV4dCB0aGF0IHN0YXJ0cyAKCSAqICAgICAgICAgICAgICAgICAgIHdpdGggdGhlIGFjY2VudHMgdG8gYmUgcmVhcnJhbmdlZAoJICogQHJldHVybiB0cnVlIGlmIHRoZSBtYXRjaCBpcyB2YWxpZCwgZmFsc2Ugb3RoZXJ3aXNlCgkgKi8KCXByaXZhdGUgYm9vbGVhbiBkb1ByZXZpb3VzQ2Fub25pY2FsTWF0Y2goaW50IHRleHRvZmZzZXQpCgl7CiAgICAgICAgaW50IG9mZnNldCA9IG1fY29sRUl0ZXJfLmdldE9mZnNldCgpOwoJICAgIGlmICgoZ2V0RkNEKHRhcmdldFRleHQsIHRleHRvZmZzZXQpID4+IFNFQ09ORF9MQVNUX0JZVEVfU0hJRlRfKSA9PSAwKSB7CgkgICAgICAgIGlmIChtX3BhdHRlcm5fLm1faGFzU3VmZml4QWNjZW50c18pIHsKCSAgICAgICAgICAgIG9mZnNldCA9IGRvUHJldmlvdXNDYW5vbmljYWxTdWZmaXhNYXRjaCh0ZXh0b2Zmc2V0LCBvZmZzZXQpOwoJICAgICAgICAgICAgaWYgKG9mZnNldCAhPSBET05FKSB7CgkgICAgICAgICAgICAgICAgbV9jb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQob2Zmc2V0KTsKCSAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgfQoJCgkgICAgaWYgKCFtX3BhdHRlcm5fLm1faGFzUHJlZml4QWNjZW50c18pIHsKCSAgICAgICAgcmV0dXJuIGZhbHNlOwoJICAgIH0KCQoJICAgIFN0cmluZ0J1ZmZlciBhY2NlbnRzID0gbmV3IFN0cmluZ0J1ZmZlcigpOwoJICAgIC8vIG9mZnNldCB0byB0aGUgbGFzdCBiYXNlIGNoYXJhY3RlciBpbiBzdWJzdHJpbmcgdG8gc2VhcmNoCgkgICAgaW50IGJhc2VvZmZzZXQgPSBnZXROZXh0QmFzZU9mZnNldCh0YXJnZXRUZXh0LCB0ZXh0b2Zmc2V0KTsKCSAgICAvLyBub3JtYWxpemluZyB0aGUgb2ZmZW5zaXZlIHN0cmluZwoJICAgIFN0cmluZyB0ZXh0c3RyID0gZ2V0U3RyaW5nKHRhcmdldFRleHQsIHRleHRvZmZzZXQsIAoJICAgIAkJCQkJCQkJCQkJYmFzZW9mZnNldCAtIHRleHRvZmZzZXQpOwoJICAgIGlmIChOb3JtYWxpemVyLnF1aWNrQ2hlY2sodGV4dHN0ciwgTm9ybWFsaXplci5ORkQsMCkgCgkgICAgICAgIAkJCQkJCQkJCQk9PSBOb3JtYWxpemVyLk5PKSB7CgkgICAgICAgIHRleHRzdHIgPSBOb3JtYWxpemVyLmRlY29tcG9zZSh0ZXh0c3RyLCBmYWxzZSk7CgkgICAgfQoJICAgIGFjY2VudHMuYXBwZW5kKHRleHRzdHIpOwoJICAgIC8vIHN0YXR1cyBjaGVja2VkIGluIGxvb3AKCSAgICAgICAgCgkgICAgaW50IGFjY2VudHNpbmRleFtdID0gbmV3IGludFtJTklUSUFMX0FSUkFZX1NJWkVfXTsKCSAgICBpbnQgc2l6ZSA9IGdldFVuYmxvY2tlZEFjY2VudEluZGV4KGFjY2VudHMsIGFjY2VudHNpbmRleCk7CgkKCSAgICAvLyAyIHBvd2VyIG4gLSAxIG1pbnVzIHRoZSBmdWxsIHNldCBvZiBhY2NlbnRzCgkgICAgaW50IGNvdW50ID0gKDIgPDwgKHNpemUgLSAxKSkgLSAyOyAgCgkgICAgd2hpbGUgKGNvdW50ID4gMCkgewoJICAgIAltX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfLmRlbGV0ZSgwLCAKCSAgICAJCQkJCQkJCW1fY2Fub25pY2FsUHJlZml4QWNjZW50c18ubGVuZ3RoKCkpOwoJICAgICAgICAvLyBjb3B5IHRoZSBiYXNlIGNoYXJhY3RlcnMKCSAgICAgICAgZm9yIChpbnQgayA9IDA7IGsgPCBhY2NlbnRzaW5kZXhbMF07IGsgKyspIHsKCSAgICAgICAgICAgIG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18uYXBwZW5kKGFjY2VudHMuY2hhckF0KGspKTsKCSAgICAgICAgfQoJICAgICAgICAvLyBmb3JtaW5nIGFsbCBwb3NzaWJsZSBjYW5vbmljYWwgcmVhcnJhbmdlbWVudCBieSBkcm9wcGluZwoJICAgICAgICAvLyBzZXRzIG9mIGFjY2VudHMKCSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc2l6ZSAtIDE7IGkgKyspIHsKCSAgICAgICAgICAgIGludCBtYXNrID0gMSA8PCAoc2l6ZSAtIGkgLSAxKTsKCSAgICAgICAgICAgIGlmICgoY291bnQgJiBtYXNrKSAhPSAwKSB7CgkgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IGFjY2VudHNpbmRleFtpXTsgaiA8IGFjY2VudHNpbmRleFtpICsgMV07IAoJICAgICAgICAgICAgICAgIAkgaiArKykgewoJICAgICAgICAgICAgICAgICAgICBtX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfLmFwcGVuZChhY2NlbnRzLmNoYXJBdChqKSk7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgICAgIG9mZnNldCA9IGRvUHJldmlvdXNDYW5vbmljYWxQcmVmaXhNYXRjaChiYXNlb2Zmc2V0KTsKCSAgICAgICAgaWYgKG9mZnNldCAhPSBET05FKSB7CgkgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gbWF0Y2ggZm91bmQKCSAgICAgICAgfQoJICAgICAgICBjb3VudCAtLTsKCSAgICB9CgkgICAgcmV0dXJuIGZhbHNlOwoJfQoJCgkvKioKCSAqIENoZWNrcyBtYXRjaCBmb3IgY29udHJhY3Rpb24uIAoJICogSWYgdGhlIG1hdGNoIHN0YXJ0cyB3aXRoIGEgcGFydGlhbCBjb250cmFjdGlvbiB3ZSBmYWlsLgoJICogVXNlcyB0aGUgdGVtcG9yYXJ5IHV0aWxpdHkgYnVmZmVyIHRvIHJldHVybiB0aGUgbW9kaWZpZWQgc3RhcnQgYW5kIGVuZC4KCSAqIEBwYXJhbSBzdGFydCBvZmZzZXQgb2YgcG90ZW50aWFsIG1hdGNoLCB0byBiZSBtb2RpZmllZCBpZiBuZWNlc3NhcnkKCSAqIEBwYXJhbSBlbmQgb2Zmc2V0IG9mIHBvdGVudGlhbCBtYXRjaCwgdG8gYmUgbW9kaWZpZWQgaWYgbmVjZXNzYXJ5CgkgKiBAcmV0dXJuIHRydWUgaWYgbWF0Y2ggcGFzc2VzIHRoZSBjb250cmFjdGlvbiB0ZXN0LCBmYWxzZSBvdGhlcndpc2UuCgkgKi8KCXByaXZhdGUgYm9vbGVhbiBjaGVja1ByZXZpb3VzQ2Fub25pY2FsQ29udHJhY3Rpb25NYXRjaChpbnQgc3RhcnQsIGludCBlbmQpIAoJewoJICAgIGludCB0ZW1wID0gZW5kOwoJICAgIC8vIFRoaXMgcGFydCBjaGVja3MgaWYgZWl0aGVyIGVuZHMgb2YgdGhlIG1hdGNoIGNvbnRhaW5zIHBvdGVudGlhbCAKCSAgICAvLyBjb250cmFjdGlvbi4gSWYgc28gd2UnbGwgaGF2ZSB0byBpdGVyYXRlIHRocm91Z2ggdGhlbQoJICAgIGNoYXIgZWNoYXIgPSAwOwoJICAgIGNoYXIgc2NoYXIgPSAwOwoJICAgIGlmIChlbmQgPCBtX3RleHRMaW1pdE9mZnNldF8pIHsKCSAgICAJdGFyZ2V0VGV4dC5zZXRJbmRleChlbmQpOwoJICAgIAllY2hhciA9IHRhcmdldFRleHQuY3VycmVudCgpOwoJICAgIH0KCSAgICBpZiAoc3RhcnQgKyAxIDwgbV90ZXh0TGltaXRPZmZzZXRfKSB7CgkgICAgCXRhcmdldFRleHQuc2V0SW5kZXgoc3RhcnQgKyAxKTsKCSAgICAJc2NoYXIgPSB0YXJnZXRUZXh0LmN1cnJlbnQoKTsKCSAgICB9CgkgICAgaWYgKG1fY29sbGF0b3JfLmlzVW5zYWZlKGVjaGFyKSB8fCBtX2NvbGxhdG9yXy5pc1Vuc2FmZShzY2hhcikpIHsKCSAgICAgICAgaW50IGV4cGFuc2lvbiA9IG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJTaXplXyAKCSAgICAgICAgCQkJCQkJCQktIG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJPZmZzZXRfOwoJICAgICAgICBib29sZWFuIGhhc0V4cGFuc2lvbiA9IGV4cGFuc2lvbiA+IDA7CgkgICAgICAgIG1fY29sRUl0ZXJfLnNldEV4YWN0T2Zmc2V0KGVuZCk7CgkgICAgICAgIHdoaWxlIChleHBhbnNpb24gPiAwKSB7CgkgICAgICAgICAgICAvLyBnZXR0aW5nIHJpZCBvZiB0aGUgcmVkdW5kYW50IGNlCgkgICAgICAgICAgICAvLyBzaW5jZSBmb3J3YXJkIGNvbnRyYWN0aW9uL2V4cGFuc2lvbiBtYXkgaGF2ZSBleHRyYSBjZXMKCSAgICAgICAgICAgIC8vIGlmIHdlIGFyZSBpbiB0aGUgbm9ybWFsaXphdGlvbiBidWZmZXIsIGhhc0FjY2VudHNCZWZvcmVNYXRjaAoJICAgICAgICAgICAgLy8gd291bGQgaGF2ZSB0YWtlbiBjYXJlIG9mIGl0LgoJICAgICAgICAgICAgLy8gRS5nLiB0aGUgY2hhcmFjdGVyIFx1MDFGQSB3aWxsIGhhdmUgYW4gZXhwYW5zaW9uIG9mIDMsIGJ1dCAKCSAgICAgICAgICAgIC8vIGlmIHdlIGFyZSBvbmx5IGxvb2tpbmcgZm9yIEEgcmluZyBBXHUwMzBBLCB3ZSdsbCBoYXZlIHRvIAoJICAgICAgICAgICAgLy8gc2tpcCB0aGUgbGFzdCBjZSBpbiB0aGUgZXhwYW5zaW9uIGJ1ZmZlcgoJICAgICAgICAgICAgbV9jb2xFSXRlcl8ucHJldmlvdXMoKTsKCSAgICAgICAgICAgIGlmIChtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKSAhPSB0ZW1wKSB7CgkgICAgICAgICAgICAgICAgZW5kID0gdGVtcDsKCSAgICAgICAgICAgICAgICB0ZW1wID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBleHBhbnNpb24gLS07CgkgICAgICAgIH0KCQoJICAgICAgICBpbnQgY291bnQgPSBtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfOwoJICAgICAgICB3aGlsZSAoY291bnQgPiAwKSB7CgkgICAgICAgICAgICBpbnQgY2UgPSBnZXRDRShtX2NvbEVJdGVyXy5wcmV2aW91cygpKTsKCSAgICAgICAgICAgIC8vIHN0YXR1cyBjaGVja2VkIGJlbG93LCBub3RlIHRoYXQgaWYgc3RhdHVzIGlzIGEgZmFpbHVyZQoJICAgICAgICAgICAgLy8gcHJldmlvdXMoKSByZXR1cm5zIE5VTExPUkRFUgoJICAgICAgICAgICAgaWYgKGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGlmIChoYXNFeHBhbnNpb24gJiYgY291bnQgPT0gMCAKCSAgICAgICAgICAgIAkmJiBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKSAhPSB0ZW1wKSB7CgkgICAgICAgICAgICAgICAgZW5kID0gdGVtcDsKCSAgICAgICAgICAgICAgICB0ZW1wID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAoY291bnQgPT0gbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyAKCSAgICAgICAgICAgIAkmJiBjZSAhPSBtX3BhdHRlcm5fLm1fQ0VfW21fcGF0dGVybl8ubV9DRUxlbmd0aF8gLSAxXSkgewoJICAgICAgICAgICAgICAgIC8vIGFjY2VudHMgbWF5IGhhdmUgZXh0cmEgc3RhcnRpbmcgY2VzLCB0aGlzIG9jY3VycyB3aGVuIGEgCgkgICAgICAgICAgICAgICAgLy8gcHVyZSBhY2NlbnQgcGF0dGVybiBpcyBtYXRjaGVkIHdpdGhvdXQgcmVhcnJhbmdlbWVudAoJICAgICAgICAgICAgICAgIGludCBleHBlY3RlZCA9IG1fcGF0dGVybl8ubV9DRV9bbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyAtIDFdOwoJICAgICAgICAgICAgICAgIHRhcmdldFRleHQuc2V0SW5kZXgoZW5kKTsKCSAgICAgICAgICAgICAgICBpZiAoVVRGMTYuaXNUcmFpbFN1cnJvZ2F0ZSh0YXJnZXRUZXh0LnByZXZpb3VzKCkpKSB7CgkgICAgICAgICAgICAgICAgCWlmICh0YXJnZXRUZXh0LmdldEluZGV4KCkgPiBtX3RleHRCZWdpbk9mZnNldF8gJiYKCSAgICAgICAgICAgICAgICAJCSFVVEYxNi5pc0xlYWRTdXJyb2dhdGUodGFyZ2V0VGV4dC5wcmV2aW91cygpKSkgewoJICAgICAgICAgICAgICAgIAkJdGFyZ2V0VGV4dC5uZXh0KCk7CgkgICAgICAgICAgICAgICAgCX0KCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgZW5kID0gdGFyZ2V0VGV4dC5nZXRJbmRleCgpOwoJICAgICAgICAgICAgICAgIGlmICgoZ2V0RkNEKHRhcmdldFRleHQsIGVuZCkgJiBMQVNUX0JZVEVfTUFTS18pICE9IDApIHsKCSAgICAgICAgICAgICAgICAgICAgY2UgPSBnZXRDRShtX2NvbEVJdGVyXy5wcmV2aW91cygpKTsKCSAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGNlICE9IGV4cGVjdGVkIAoJICAgICAgICAgICAgICAgICAgICAJCSYmIGNlICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIgCgkgICAgICAgICAgICAgICAgICAgIAkJJiYgbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCkgPD0gc3RhcnQpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIGNlID0gZ2V0Q0UobV9jb2xFSXRlcl8ucHJldmlvdXMoKSk7CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAoY2UgIT0gbV9wYXR0ZXJuXy5tX0NFX1tjb3VudCAtIDFdKSB7CgkgICAgICAgICAgICAgICAgc3RhcnQgLS07CgkgICAgICAgICAgICAgICAgc3RhcnQgPSBnZXRQcmV2aW91c0Jhc2VPZmZzZXQoc3RhcnQpOwoJICAgICAgICAgICAgICAgIG1fdXRpbEJ1ZmZlcl9bMF0gPSBzdGFydDsKCSAgICAgICAgICAgICAgICBtX3V0aWxCdWZmZXJfWzFdID0gZW5kOwoJICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGNvdW50IC0tOwoJICAgICAgICB9CgkgICAgfSAKCSAgICBtX3V0aWxCdWZmZXJfWzBdID0gc3RhcnQ7CgkgICAgbV91dGlsQnVmZmVyX1sxXSA9IGVuZDsKCSAgICByZXR1cm4gdHJ1ZTsKCX0KCQoJLyoqCgkgKiBDaGVja3MgYW5kIHNldHMgdGhlIG1hdGNoIGluZm9ybWF0aW9uIGlmIGZvdW5kLgoJICogQ2hlY2tzIAoJICogPHVsPgoJICogPGxpPiB0aGUgcG90ZW50aWFsIG1hdGNoIGRvZXMgbm90IHJlcGVhdCB0aGUgcHJldmlvdXMgbWF0Y2gKCSAqIDxsaT4gYm91bmRhcmllcyBhcmUgY29ycmVjdAoJICogPGxpPiBwb3RlbnRpYWwgbWF0Y2ggZG9lcyBub3QgZW5kIGluIHRoZSBtaWRkbGUgb2YgYSBjb250cmFjdGlvbgoJICogPGxpPiBpZGVudGljYWwgbWF0Y2hlcwoJICogPC91bD4KCSAqIE90aGVyd2lzZSB0aGUgb2Zmc2V0IHdpbGwgYmUgc2hpZnRlZCB0byB0aGUgbmV4dCBjaGFyYWN0ZXIuCgkgKiBVc2VzIHRoZSB0ZW1wb3JhcnkgdXRpbGl0eSBidWZmZXIgZm9yIHN0b3JpbmcgdGhlIG1vZGlmaWVkIHRleHRvZmZzZXQuCgkgKiBAcGFyYW0gdGV4dG9mZnNldCBvZmZzZXQgaW4gdGhlIGNvbGxhdGlvbiBlbGVtZW50IHRleHQuIHRoZSByZXR1cm5lZCAKCSAqIAkJCXZhbHVlIHdpbGwgYmUgdGhlIHRydW5jYXRlZCBzdGFydCBvZmZzZXQgb2YgdGhlIG1hdGNoIG9yIHRoZSAKCSAqIAkJCW5ldyBzdGFydCBzZWFyY2ggb2Zmc2V0LgoJICogQHJldHVybiB0cnVlIGlmIHRoZSBtYXRjaCBpcyB2YWxpZCwgZmFsc2Ugb3RoZXJ3aXNlCgkgKi8KCXByaXZhdGUgYm9vbGVhbiBjaGVja1ByZXZpb3VzQ2Fub25pY2FsTWF0Y2goaW50IHRleHRvZmZzZXQpCgl7CgkgICAgLy8gdG8gZW5zdXJlIHRoYXQgdGhlIHN0YXJ0IGFuZCBlbmRzIGFyZSBub3QgY29tcG9zaXRlIGNoYXJhY3RlcnMKCSAgICAvLyBpZiB3ZSBoYXZlIGEgY2Fub25pY2FsIGFjY2VudCBtYXRjaAoJICAgIGlmIChtX3BhdHRlcm5fLm1faGFzU3VmZml4QWNjZW50c18gCgkgICAgCSYmIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18ubGVuZ3RoKCkgIT0gMCAKCSAgICAJfHwgbV9wYXR0ZXJuXy5tX2hhc1ByZWZpeEFjY2VudHNfIAoJICAgIAkmJiBtX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfLmxlbmd0aCgpICE9IDApIHsKCSAgICAgICAgbV9tYXRjaGVkSW5kZXhfID0gdGV4dG9mZnNldDsKCSAgICAgICAgbWF0Y2hMZW5ndGggPSBnZXROZXh0QmFzZU9mZnNldChtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKSkgCgkgICAgICAgICAgICAJCQkJCQkJCQkJCQktIHRleHRvZmZzZXQ7CgkgICAgICAgIHJldHVybiB0cnVlOwoJICAgIH0KCQoJICAgIGludCBlbmQgPSBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKTsKCSAgICBpZiAoIWNoZWNrUHJldmlvdXNDYW5vbmljYWxDb250cmFjdGlvbk1hdGNoKHRleHRvZmZzZXQsIGVuZCkpIHsKCSAgICAJLy8gc3RvcmluZyB0aGUgbW9kaWZpZWQgdGV4dG9mZnNldAoJICAgIAlyZXR1cm4gZmFsc2U7CgkgICAgfQoJICAgIHRleHRvZmZzZXQgPSBtX3V0aWxCdWZmZXJfWzBdOwoJCWVuZCA9IG1fdXRpbEJ1ZmZlcl9bMV07CgkgICAgZW5kID0gZ2V0TmV4dEJhc2VPZmZzZXQoZW5kKTsKCSAgICAvLyB0aGlzIHRvdGFsbHkgbWF0Y2hlcywgaG93ZXZlciB3ZSBuZWVkIHRvIGNoZWNrIGlmIGl0IGlzIHJlcGVhdGluZwoJICAgIGlmIChjaGVja1JlcGVhdGVkTWF0Y2godGV4dG9mZnNldCwgZW5kKSAKCSAgICAJfHwgIWlzQnJlYWtVbml0KHRleHRvZmZzZXQsIGVuZCkgCgkgICAgCXx8ICFjaGVja0lkZW50aWNhbCh0ZXh0b2Zmc2V0LCBlbmQpKSB7CgkgICAgICAgIHRleHRvZmZzZXQgLS07CgkgICAgICAgIHRleHRvZmZzZXQgPSBnZXRQcmV2aW91c0Jhc2VPZmZzZXQodGV4dG9mZnNldCk7CgkgICAgICAgIG1fdXRpbEJ1ZmZlcl9bMF0gPSB0ZXh0b2Zmc2V0OwoJICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgfQoJICAgIAoJICAgIG1fbWF0Y2hlZEluZGV4XyA9IHRleHRvZmZzZXQ7CgkgICAgbWF0Y2hMZW5ndGggPSBlbmQgLSB0ZXh0b2Zmc2V0OwoJICAgIHJldHVybiB0cnVlOwoJfQoJCgkvKioKCSAqIE1ldGhvZCB0aGF0IGRvZXMgdGhlIG5leHQgZXhhY3QgbWF0Y2gKCSAqIEBwYXJhbSBzdGFydCB0aGUgb2Zmc2V0IHRvIHN0YXJ0IHNoaWZ0aW5nIGZyb20gYW5kIHBlcmZvcm1pbmcgdGhlIAoJICogICAgICAgIG5leHQgZXhhY3QgbWF0Y2gKCSAqLwoJcHJpdmF0ZSB2b2lkIGhhbmRsZU5leHRFeGFjdChpbnQgc3RhcnQpCgl7CgkgICAJaW50IHRleHRvZmZzZXQgPSBzaGlmdEZvcndhcmQoc3RhcnQsIAoJICAgCQkJCQkJCQkgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIsCgkgICAJCQkJCQkJCSAgbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyk7CgkJaW50IHRhcmdldGNlID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRTsKCSAgICB3aGlsZSAodGV4dG9mZnNldCA8PSBtX3RleHRMaW1pdE9mZnNldF8pIHsKICAgICAgICAgICAgbV9jb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQodGV4dG9mZnNldCk7CgkgICAgICAgIGludCBwYXR0ZXJuY2VpbmRleCA9IG1fcGF0dGVybl8ubV9DRUxlbmd0aF8gLSAxOwoJICAgICAgICBib29sZWFuIGZvdW5kID0gZmFsc2U7CgkgICAgICAgIGludCBsYXN0Y2UgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSOwoJICAgICAgICAKCSAgICAgICAgd2hpbGUgKHRydWUpIHsKCSAgICAgICAgICAgIC8vIGZpbmRpbmcgdGhlIGxhc3QgcGF0dGVybiBjZSBtYXRjaCwgaW1hZ2luZSBjb21wb3NpdGUgCgkgICAgICAgICAgICAvLyBjaGFyYWN0ZXJzLiBmb3IgZXhhbXBsZTogc2VhcmNoIGZvciBwYXR0ZXJuIEEgaW4gdGV4dCBcdTAwQzAKCSAgICAgICAgICAgIC8vIHdlJ2xsIGhhdmUgdG8gc2tpcCBcdTAzMDAgdGhlIGdyYXZlIGZpcnN0IGJlZm9yZSB3ZSBnZXQgdG8gQQoJICAgICAgICAgICAgdGFyZ2V0Y2UgPSBtX2NvbEVJdGVyXy5wcmV2aW91cygpOwoJICAgICAgICAgICAgaWYgKHRhcmdldGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKCSAgICAgICAgICAgICAgICBmb3VuZCA9IGZhbHNlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgdGFyZ2V0Y2UgPSBnZXRDRSh0YXJnZXRjZSk7CgkgICAgICAgICAgICBpZiAodGFyZ2V0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSAmJiAKCSAgICAgICAgICAgIAltX2NvbEVJdGVyXy5pc0luQnVmZmVyKCkpIHsgCgkgICAgICAgICAgICAgICAgLy8gdGhpcyBpcyBmb3IgdGhlIHRleHQgXHUwMzE1XHUwMzAwIHRoYXQgcmVxdWlyZXMgCgkgICAgICAgICAgICAgICAgLy8gbm9ybWFsaXphdGlvbiBhbmQgcGF0dGVybiBcdTAzMDAsIHdoZXJlIFx1MDMxNSBpcyBpZ25vcmFibGUKCSAgICAgICAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGlmIChsYXN0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUiAKCSAgICAgICAgICAgIAl8fCBsYXN0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgICAgIGxhc3RjZSA9IHRhcmdldGNlOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKHRhcmdldGNlID09IG1fcGF0dGVybl8ubV9DRV9bcGF0dGVybmNlaW5kZXhdKSB7CgkgICAgICAgICAgICAgICAgLy8gdGhlIGZpcnN0IGNlIGNhbiBiZSBhIGNvbnRyYWN0aW9uCgkgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJPZmZzZXRfIDw9IDApIHsKCSAgICAgICAgICAgICAgICBmb3VuZCA9IGZhbHNlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkKCSAgICAgICAgdGFyZ2V0Y2UgPSBsYXN0Y2U7CgkgICAgICAgIAoJICAgICAgICB3aGlsZSAoZm91bmQgJiYgcGF0dGVybmNlaW5kZXggPiAwKSB7CgkgICAgICAgICAgICB0YXJnZXRjZSA9IG1fY29sRUl0ZXJfLnByZXZpb3VzKCk7CgkgICAgICAgICAgICBpZiAodGFyZ2V0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewoJICAgICAgICAgICAgICAgIGZvdW5kID0gZmFsc2U7CgkgICAgICAgICAgICAgICAgYnJlYWs7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICB0YXJnZXRjZSA9IGdldENFKHRhcmdldGNlKTsKCSAgICAgICAgICAgIGlmICh0YXJnZXRjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CgkgICAgICAgICAgICAgICAgY29udGludWU7CgkgICAgICAgICAgICB9CgkKCSAgICAgICAgICAgIHBhdHRlcm5jZWluZGV4IC0tOwoJICAgICAgICAgICAgZm91bmQgPSBmb3VuZCAmJiB0YXJnZXRjZSA9PSBtX3BhdHRlcm5fLm1fQ0VfW3BhdHRlcm5jZWluZGV4XTsgCgkgICAgICAgIH0KCQoJICAgICAgICBpZiAoIWZvdW5kKSB7CgkgICAgICAgICAgICB0ZXh0b2Zmc2V0ID0gc2hpZnRGb3J3YXJkKHRleHRvZmZzZXQsIHRhcmdldGNlLCAKCSAgICAgICAgICAgIAkJCQkJCQkJCQkJcGF0dGVybmNlaW5kZXgpOwoJICAgICAgICAgICAgLy8gc3RhdHVzIGNoZWNrZWQgYXQgbG9vcC4KCSAgICAgICAgICAgIHBhdHRlcm5jZWluZGV4ID0gbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXzsKCSAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICB9CgkgICAgICAgIAoJICAgICAgICBpZiAoY2hlY2tOZXh0RXhhY3RNYXRjaCh0ZXh0b2Zmc2V0KSkgewoJICAgICAgICAgICAgLy8gc3RhdHVzIGNoZWNrZWQgaW4gdWNvbF9zZXRPZmZzZXQKCSAgICAgICAgICAgIHJldHVybjsKCSAgICAgICAgfQoJICAgICAgICB0ZXh0b2Zmc2V0ID0gbV91dGlsQnVmZmVyX1swXTsKCSAgICB9CgkgICAgc2V0TWF0Y2hOb3RGb3VuZCgpOwoJfQoKCS8qKgoJICogTWV0aG9kIHRoYXQgZG9lcyB0aGUgbmV4dCBjYW5vbmljYWwgbWF0Y2gKCSAqIEBwYXJhbSBzdGFydCB0aGUgb2Zmc2V0IHRvIHN0YXJ0IHNoaWZ0aW5nIGZyb20gYW5kIHBlcmZvcm1pbmcgdGhlIAoJICogICAgICAgIG5leHQgY2Fub25pY2FsIG1hdGNoCgkgKi8KCXByaXZhdGUgdm9pZCBoYW5kbGVOZXh0Q2Fub25pY2FsKGludCBzdGFydCkKCXsKCSAgICBib29sZWFuIGhhc1BhdHRlcm5BY2NlbnRzID0gCgkgICAgICAgbV9wYXR0ZXJuXy5tX2hhc1N1ZmZpeEFjY2VudHNfIHx8IG1fcGF0dGVybl8ubV9oYXNQcmVmaXhBY2NlbnRzXzsKCSAgICAgICAgICAKCSAgICAvLyBzaGlmdGluZyBpdCBjaGVjayBmb3Igc2V0dGluZyBvZmZzZXQKCSAgICAvLyBpZiBzZXRPZmZzZXQgaXMgY2FsbGVkIHByZXZpb3VzbHkgb3IgdGhlcmUgd2FzIG5vIHByZXZpb3VzIG1hdGNoLCB3ZQoJICAgIC8vIGxlYXZlIHRoZSBvZmZzZXQgYXMgaXQgaXMuCgkgICAgaW50IHRleHRvZmZzZXQgPSBzaGlmdEZvcndhcmQoc3RhcnQsIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIsIAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCSAgbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyk7CgkgICAgbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5kZWxldGUoMCwgbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5sZW5ndGgoKSk7CgkgICAgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5kZWxldGUoMCwgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5sZW5ndGgoKSk7CgkJaW50IHRhcmdldGNlID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRTsKCSAgICAKCSAgICB3aGlsZSAodGV4dG9mZnNldCA8PSBtX3RleHRMaW1pdE9mZnNldF8pCgkgICAgewoJICAgIAltX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldCh0ZXh0b2Zmc2V0KTsKCSAgICAgICAgaW50IHBhdHRlcm5jZWluZGV4ID0gbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyAtIDE7CgkgICAgICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKCSAgICAgICAgaW50IGxhc3RjZSA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVI7CgkgICAgICAgIAoJICAgICAgICB3aGlsZSAodHJ1ZSkgewoJICAgICAgICAgICAgLy8gZmluZGluZyB0aGUgbGFzdCBwYXR0ZXJuIGNlIG1hdGNoLCBpbWFnaW5lIGNvbXBvc2l0ZSBjaGFyYWN0ZXJzCgkgICAgICAgICAgICAvLyBmb3IgZXhhbXBsZTogc2VhcmNoIGZvciBwYXR0ZXJuIEEgaW4gdGV4dCBcdTAwQzAKCSAgICAgICAgICAgIC8vIHdlJ2xsIGhhdmUgdG8gc2tpcCBcdTAzMDAgdGhlIGdyYXZlIGZpcnN0IGJlZm9yZSB3ZSBnZXQgdG8gQQoJICAgICAgICAgICAgdGFyZ2V0Y2UgPSBtX2NvbEVJdGVyXy5wcmV2aW91cygpOwoJICAgICAgICAgICAgaWYgKHRhcmdldGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKCSAgICAgICAgICAgICAgICBmb3VuZCA9IGZhbHNlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgdGFyZ2V0Y2UgPSBnZXRDRSh0YXJnZXRjZSk7CgkgICAgICAgICAgICBpZiAobGFzdGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIgCgkgICAgICAgICAgICAJCQl8fCBsYXN0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgICAgIGxhc3RjZSA9IHRhcmdldGNlOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKHRhcmdldGNlID09IG1fcGF0dGVybl8ubV9DRV9bcGF0dGVybmNlaW5kZXhdKSB7CgkgICAgICAgICAgICAgICAgLy8gdGhlIGZpcnN0IGNlIGNhbiBiZSBhIGNvbnRyYWN0aW9uCgkgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJPZmZzZXRfIDw9IDApIHsKCSAgICAgICAgICAgICAgICBmb3VuZCA9IGZhbHNlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgICAgIHRhcmdldGNlID0gbGFzdGNlOwoJICAgICAgICAKCSAgICAgICAgd2hpbGUgKGZvdW5kICYmIHBhdHRlcm5jZWluZGV4ID4gMCkgewoJICAgICAgICAgICAgdGFyZ2V0Y2UgICAgPSBtX2NvbEVJdGVyXy5wcmV2aW91cygpOwoJICAgICAgICAgICAgaWYgKHRhcmdldGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKCSAgICAgICAgICAgICAgICBmb3VuZCA9IGZhbHNlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgdGFyZ2V0Y2UgICAgPSBnZXRDRSh0YXJnZXRjZSk7CgkgICAgICAgICAgICBpZiAodGFyZ2V0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICAgICAgfQoJCgkgICAgICAgICAgICBwYXR0ZXJuY2VpbmRleCAtLTsKCSAgICAgICAgICAgIGZvdW5kID0gZm91bmQgJiYgdGFyZ2V0Y2UgPT0gbV9wYXR0ZXJuXy5tX0NFX1twYXR0ZXJuY2VpbmRleF07IAoJICAgICAgICB9CgkKCSAgICAgICAgLy8gaW5pdGlhbGl6aW5nIHRoZSByZWFycmFuZ2VkIGFjY2VudCBhcnJheQoJICAgICAgICBpZiAoaGFzUGF0dGVybkFjY2VudHMgJiYgIWZvdW5kKSB7CgkgICAgICAgICAgICBmb3VuZCA9IGRvTmV4dENhbm9uaWNhbE1hdGNoKHRleHRvZmZzZXQpOwoJICAgICAgICB9CgkKCSAgICAgICAgaWYgKCFmb3VuZCkgewoJICAgICAgICAgICAgdGV4dG9mZnNldCA9IHNoaWZ0Rm9yd2FyZCh0ZXh0b2Zmc2V0LCB0YXJnZXRjZSwgcGF0dGVybmNlaW5kZXgpOwoJICAgICAgICAgICAgLy8gc3RhdHVzIGNoZWNrZWQgYXQgbG9vcAoJICAgICAgICAgICAgcGF0dGVybmNlaW5kZXggPSBtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfOwoJICAgICAgICAgICAgY29udGludWU7CgkgICAgICAgIH0KCSAgICAgICAgCgkgICAgICAgIGlmIChjaGVja05leHRDYW5vbmljYWxNYXRjaCh0ZXh0b2Zmc2V0KSkgewoJICAgICAgICAgICAgcmV0dXJuOwoJICAgICAgICB9CgkgICAgICAgIHRleHRvZmZzZXQgPSBtX3V0aWxCdWZmZXJfWzBdOwoJICAgIH0KCSAgICBzZXRNYXRjaE5vdEZvdW5kKCk7Cgl9CgkKCS8qKgoJICogTWV0aG9kIHRoYXQgZG9lcyB0aGUgcHJldmlvdXMgZXhhY3QgbWF0Y2gKCSAqIEBwYXJhbSBzdGFydCB0aGUgb2Zmc2V0IHRvIHN0YXJ0IHNoaWZ0aW5nIGZyb20gYW5kIHBlcmZvcm1pbmcgdGhlIAoJICogICAgICAgIHByZXZpb3VzIGV4YWN0IG1hdGNoCgkgKi8KCXByaXZhdGUgdm9pZCBoYW5kbGVQcmV2aW91c0V4YWN0KGludCBzdGFydCkKCXsKCSAgICBpbnQgdGV4dG9mZnNldCA9IHJldmVyc2VTaGlmdChzdGFydCwgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUiwgCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyk7CgkgICAgd2hpbGUgKHRleHRvZmZzZXQgPj0gbV90ZXh0QmVnaW5PZmZzZXRfKQoJICAgIHsKCSAgICAJbV9jb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQodGV4dG9mZnNldCk7CgkgICAgICAgIGludCBwYXR0ZXJuY2VpbmRleCA9IDE7CgkgICAgICAgIGludCB0YXJnZXRjZSA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEU7CgkgICAgICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKCSAgICAgICAgaW50IGZpcnN0Y2UgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSOwoJICAgICAgICAKCSAgICAgICAgd2hpbGUgKHRydWUpIHsKCSAgICAgICAgICAgIC8vIGZpbmRpbmcgdGhlIGZpcnN0IHBhdHRlcm4gY2UgbWF0Y2gsIGltYWdpbmUgY29tcG9zaXRlIAoJICAgICAgICAgICAgLy8gY2hhcmFjdGVycy4gZm9yIGV4YW1wbGU6IHNlYXJjaCBmb3IgcGF0dGVybiBcdTAzMDAgaW4gdGV4dCAKCSAgICAgICAgICAgIC8vIFx1MDBDMCwgd2UnbGwgaGF2ZSB0byBza2lwIEEgZmlyc3QgYmVmb3JlIHdlIGdldCB0byAKCSAgICAgICAgICAgIC8vIFx1MDMwMCB0aGUgZ3JhdmUgYWNjZW50CgkgICAgICAgICAgICB0YXJnZXRjZSA9IG1fY29sRUl0ZXJfLm5leHQoKTsKCSAgICAgICAgICAgIGlmICh0YXJnZXRjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CgkgICAgICAgICAgICAgICAgZm91bmQgPSBmYWxzZTsKCSAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHRhcmdldGNlID0gZ2V0Q0UodGFyZ2V0Y2UpOwoJICAgICAgICAgICAgaWYgKGZpcnN0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUiAKCSAgICAgICAgICAgIAl8fCBmaXJzdGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgICAgICBmaXJzdGNlID0gdGFyZ2V0Y2U7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAodGFyZ2V0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICAgICAgfSAgICAgICAgIAoJICAgICAgICAgICAgaWYgKHRhcmdldGNlID09IG1fcGF0dGVybl8ubV9DRV9bMF0pIHsKCSAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CgkgICAgICAgICAgICAgICAgYnJlYWs7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAobV9jb2xFSXRlcl8ubV9DRUJ1ZmZlck9mZnNldF8gPT0gLTEgCgkgICAgICAgICAgICAJfHwgbV9jb2xFSXRlcl8ubV9DRUJ1ZmZlck9mZnNldF8gCgkgICAgICAgICAgICAJCQkJCQkJPT0gbV9jb2xFSXRlcl8ubV9DRUJ1ZmZlclNpemVfKSB7CgkgICAgICAgICAgICAgICAgLy8gY2hlY2tpbmcgZm9yIGFjY2VudHMgaW4gY29tcG9zaXRlIGNoYXJhY3RlcgoJICAgICAgICAgICAgICAgIGZvdW5kID0gZmFsc2U7CgkgICAgICAgICAgICAgICAgYnJlYWs7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCQoJICAgICAgICB0YXJnZXRjZSA9IGZpcnN0Y2U7CgkgICAgICAgIAoJICAgICAgICB3aGlsZSAoZm91bmQgJiYgcGF0dGVybmNlaW5kZXggPCBtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfKSB7CgkgICAgICAgICAgICB0YXJnZXRjZSA9IG1fY29sRUl0ZXJfLm5leHQoKTsKCSAgICAgICAgICAgIGlmICh0YXJnZXRjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CgkgICAgICAgICAgICAgICAgZm91bmQgPSBmYWxzZTsKCSAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHRhcmdldGNlID0gZ2V0Q0UodGFyZ2V0Y2UpOwoJICAgICAgICAgICAgaWYgKHRhcmdldGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgICAgIH0KCQoJICAgICAgICAgICAgZm91bmQgPSBmb3VuZCAmJiB0YXJnZXRjZSA9PSBtX3BhdHRlcm5fLm1fQ0VfW3BhdHRlcm5jZWluZGV4XTsgCgkgICAgICAgICAgICBwYXR0ZXJuY2VpbmRleCArKzsKCSAgICAgICAgfQoJCgkgICAgICAgIGlmICghZm91bmQpIHsKCSAgICAgICAgICAgIHRleHRvZmZzZXQgPSByZXZlcnNlU2hpZnQodGV4dG9mZnNldCwgdGFyZ2V0Y2UsIHBhdHRlcm5jZWluZGV4KTsKCSAgICAgICAgICAgIHBhdHRlcm5jZWluZGV4ID0gMDsKCSAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICB9CgkgICAgICAgIAoJICAgICAgICBpZiAoY2hlY2tQcmV2aW91c0V4YWN0TWF0Y2godGV4dG9mZnNldCkpIHsKCSAgICAgICAgICAgIHJldHVybjsKCSAgICAgICAgfQoJICAgICAgICB0ZXh0b2Zmc2V0ID0gbV91dGlsQnVmZmVyX1swXTsKCSAgICB9CgkgICAgc2V0TWF0Y2hOb3RGb3VuZCgpOwoJfQoJCgkvKioKCSAqIE1ldGhvZCB0aGF0IGRvZXMgdGhlIHByZXZpb3VzIGNhbm9uaWNhbCBtYXRjaAoJICogQHBhcmFtIHN0YXJ0IHRoZSBvZmZzZXQgdG8gc3RhcnQgc2hpZnRpbmcgZnJvbSBhbmQgcGVyZm9ybWluZyB0aGUgCgkgKiAgICAgICAgcHJldmlvdXMgY2Fub25pY2FsIG1hdGNoCgkgKi8KCXByaXZhdGUgdm9pZCBoYW5kbGVQcmV2aW91c0Nhbm9uaWNhbChpbnQgc3RhcnQpCgl7CgkgICAgYm9vbGVhbiBoYXNQYXR0ZXJuQWNjZW50cyA9IAoJICAgICAgIG1fcGF0dGVybl8ubV9oYXNTdWZmaXhBY2NlbnRzXyB8fCBtX3BhdHRlcm5fLm1faGFzUHJlZml4QWNjZW50c187CgkgICAgICAgICAgCgkgICAgLy8gc2hpZnRpbmcgaXQgY2hlY2sgZm9yIHNldHRpbmcgb2Zmc2V0CgkgICAgLy8gaWYgc2V0T2Zmc2V0IGlzIGNhbGxlZCBwcmV2aW91c2x5IG9yIHRoZXJlIHdhcyBubyBwcmV2aW91cyBtYXRjaCwgd2UKCSAgICAvLyBsZWF2ZSB0aGUgb2Zmc2V0IGFzIGl0IGlzLgoJICAgIGludCB0ZXh0b2Zmc2V0ID0gcmV2ZXJzZVNoaWZ0KHN0YXJ0LCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSLCAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAkJbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyk7CgkgICAgbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5kZWxldGUoMCwgbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5sZW5ndGgoKSk7CgkgICAgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5kZWxldGUoMCwgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5sZW5ndGgoKSk7CgkgICAgCgkgICAgd2hpbGUgKHRleHRvZmZzZXQgPj0gbV90ZXh0QmVnaW5PZmZzZXRfKQoJICAgIHsKCSAgICAJbV9jb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQodGV4dG9mZnNldCk7CgkgICAgICAgIGludCBwYXR0ZXJuY2VpbmRleCA9IDE7CgkgICAgICAgIGludCB0YXJnZXRjZSA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEU7CgkgICAgICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKCSAgICAgICAgaW50IGZpcnN0Y2UgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSOwoJICAgICAgICAKCSAgICAgICAgd2hpbGUgKHRydWUpIHsKCSAgICAgICAgICAgIC8vIGZpbmRpbmcgdGhlIGZpcnN0IHBhdHRlcm4gY2UgbWF0Y2gsIGltYWdpbmUgY29tcG9zaXRlIAoJICAgICAgICAgICAgLy8gY2hhcmFjdGVycy4gZm9yIGV4YW1wbGU6IHNlYXJjaCBmb3IgcGF0dGVybiBcdTAzMDAgaW4gdGV4dCAKCSAgICAgICAgICAgIC8vIFx1MDBDMCwgd2UnbGwgaGF2ZSB0byBza2lwIEEgZmlyc3QgYmVmb3JlIHdlIGdldCB0byAKCSAgICAgICAgICAgIC8vIFx1MDMwMCB0aGUgZ3JhdmUgYWNjZW50CgkgICAgICAgICAgICB0YXJnZXRjZSA9IG1fY29sRUl0ZXJfLm5leHQoKTsKCSAgICAgICAgICAgIGlmICh0YXJnZXRjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CgkgICAgICAgICAgICAgICAgZm91bmQgPSBmYWxzZTsKCSAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHRhcmdldGNlID0gZ2V0Q0UodGFyZ2V0Y2UpOwoJICAgICAgICAgICAgaWYgKGZpcnN0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUiAKCSAgICAgICAgICAgIAl8fCBmaXJzdGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgICAgICBmaXJzdGNlID0gdGFyZ2V0Y2U7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICAKCSAgICAgICAgICAgIGlmICh0YXJnZXRjZSA9PSBtX3BhdHRlcm5fLm1fQ0VfWzBdKSB7CgkgICAgICAgICAgICAgICAgLy8gdGhlIGZpcnN0IGNlIGNhbiBiZSBhIGNvbnRyYWN0aW9uCgkgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJPZmZzZXRfID09IC0xIAoJICAgICAgICAgICAgCXx8IG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJPZmZzZXRfIAoJICAgICAgICAgICAgCQkJCQkJCT09IG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJTaXplXykgewoJICAgICAgICAgICAgICAgIC8vIGNoZWNraW5nIGZvciBhY2NlbnRzIGluIGNvbXBvc2l0ZSBjaGFyYWN0ZXIKCSAgICAgICAgICAgICAgICBmb3VuZCA9IGZhbHNlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkKCSAgICAgICAgdGFyZ2V0Y2UgPSBmaXJzdGNlOwoJICAgICAgICAKCSAgICAgICAgd2hpbGUgKGZvdW5kICYmIHBhdHRlcm5jZWluZGV4IDwgbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXykgewoJICAgICAgICAgICAgdGFyZ2V0Y2UgPSBtX2NvbEVJdGVyXy5uZXh0KCk7CgkgICAgICAgICAgICBpZiAodGFyZ2V0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewoJICAgICAgICAgICAgICAgIGZvdW5kID0gZmFsc2U7CgkgICAgICAgICAgICAgICAgYnJlYWs7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICB0YXJnZXRjZSA9IGdldENFKHRhcmdldGNlKTsKCSAgICAgICAgICAgIGlmICh0YXJnZXRjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CgkgICAgICAgICAgICAgICAgY29udGludWU7CgkgICAgICAgICAgICB9CgkKCSAgICAgICAgICAgIGZvdW5kID0gZm91bmQgJiYgdGFyZ2V0Y2UgPT0gbV9wYXR0ZXJuXy5tX0NFX1twYXR0ZXJuY2VpbmRleF07IAoJICAgICAgICAgICAgcGF0dGVybmNlaW5kZXggKys7CgkgICAgICAgIH0KCQoJICAgICAgICAvLyBpbml0aWFsaXppbmcgdGhlIHJlYXJyYW5nZWQgYWNjZW50IGFycmF5CgkgICAgICAgIGlmIChoYXNQYXR0ZXJuQWNjZW50cyAmJiAhZm91bmQpIHsKCSAgICAgICAgICAgIGZvdW5kID0gZG9QcmV2aW91c0Nhbm9uaWNhbE1hdGNoKHRleHRvZmZzZXQpOwoJICAgICAgICB9CgkKCSAgICAgICAgaWYgKCFmb3VuZCkgewoJICAgICAgICAgICAgdGV4dG9mZnNldCA9IHJldmVyc2VTaGlmdCh0ZXh0b2Zmc2V0LCB0YXJnZXRjZSwgcGF0dGVybmNlaW5kZXgpOwoJICAgICAgICAgICAgcGF0dGVybmNlaW5kZXggPSAwOwoJICAgICAgICAgICAgY29udGludWU7CgkgICAgICAgIH0KCQoJICAgICAgICBpZiAoY2hlY2tQcmV2aW91c0Nhbm9uaWNhbE1hdGNoKHRleHRvZmZzZXQpKSB7CgkgICAgICAgICAgICByZXR1cm47CgkgICAgICAgIH0KCSAgICAgICAgdGV4dG9mZnNldCA9IG1fdXRpbEJ1ZmZlcl9bMF07CgkgICAgfQoJICAgIHNldE1hdGNoTm90Rm91bmQoKTsKCX0KCQoJLyoqCgkgKiBHZXRzIGEgc3Vic3RyaW5nIG91dCBvZiBhIENoYXJhY3Rlckl0ZXJhdG9yCgkgKiBAcGFyYW0gdGV4dCBDaGFyYWN0ZXJJdGVyYXRvcgoJICogQHBhcmFtIHN0YXJ0IHN0YXJ0IG9mZnNldAoJICogQHBhcmFtIGxlbmd0aCBvZiBzdWJzdHJpbmcKCSAqIEByZXR1cm4gc3Vic3RyaW5nIGZyb20gdGV4dCBzdGFydGluZyBhdCBzdGFydCBhbmQgbGVuZ3RoIGxlbmd0aAoJICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZ2V0U3RyaW5nKENoYXJhY3Rlckl0ZXJhdG9yIHRleHQsIGludCBzdGFydCwKCQkJCQkJCQkJCQlpbnQgbGVuZ3RoKQoJewoJCVN0cmluZ0J1ZmZlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVmZmVyKGxlbmd0aCk7CgkJaW50IG9mZnNldCA9IHRleHQuZ2V0SW5kZXgoKTsKCQl0ZXh0LnNldEluZGV4KHN0YXJ0KTsKCQlmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSArKykgewoJCQlyZXN1bHQuYXBwZW5kKHRleHQuY3VycmVudCgpKTsKCQkJdGV4dC5uZXh0KCk7CgkJfQoJCXRleHQuc2V0SW5kZXgob2Zmc2V0KTsKCQlyZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7Cgl9CgkKCS8qKgoJICogR2V0dGluZyB0aGUgbWFzayBmb3IgY29sbGF0aW9uIHN0cmVuZ3RoCgkgKiBAcGFyYW0gc3RyZW5ndGggY29sbGF0aW9uIHN0cmVuZ3RoCiAJICogQHJldHVybiBjb2xsYXRpb24gZWxlbWVudCBtYXNrCgkgKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBnZXRNYXNrKGludCBzdHJlbmd0aCkgCgl7CgkgICAgc3dpdGNoIChzdHJlbmd0aCkgCgkgICAgewoJICAgIAljYXNlIENvbGxhdG9yLlBSSU1BUlk6CgkgICAgICAgIAlyZXR1cm4gUnVsZUJhc2VkQ29sbGF0b3IuQ0VfUFJJTUFSWV9NQVNLXzsKCSAgICAJY2FzZSBDb2xsYXRvci5TRUNPTkRBUlk6CgkgICAgICAgIAlyZXR1cm4gUnVsZUJhc2VkQ29sbGF0b3IuQ0VfU0VDT05EQVJZX01BU0tfIAoJICAgICAgICAJICAgICAgIHwgUnVsZUJhc2VkQ29sbGF0b3IuQ0VfUFJJTUFSWV9NQVNLXzsKCSAgICAJZGVmYXVsdDoKCSAgICAgICAgCXJldHVybiBSdWxlQmFzZWRDb2xsYXRvci5DRV9URVJUSUFSWV9NQVNLXyAKCSAgICAgICAgCSAgICAgICB8IFJ1bGVCYXNlZENvbGxhdG9yLkNFX1NFQ09OREFSWV9NQVNLXyAKCSAgICAgICAgICAgICAgICAgICB8IFJ1bGVCYXNlZENvbGxhdG9yLkNFX1BSSU1BUllfTUFTS187CgkgICAgfQoJfQogICAgCiAgICAvKioKICAgICAqIFNldHMgbWF0Y2ggbm90IGZvdW5kIAogICAgICovCiAgICBwcml2YXRlIHZvaWQgc2V0TWF0Y2hOb3RGb3VuZCgpIAogICAgewogICAgICAgIC8vIHRoaXMgbWV0aG9kIHJlc2V0cyB0aGUgbWF0Y2ggcmVzdWx0IHJlZ2FyZGxlc3Mgb2YgdGhlIGVycm9yIHN0YXR1cy4KICAgICAgICBtX21hdGNoZWRJbmRleF8gPSBET05FOwogICAgICAgIHNldE1hdGNoTGVuZ3RoKDApOwogICAgfQp9Cg==