LyoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChDKSAxOTk2LTIwMDAsIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kICAgICoKICogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogJFNvdXJjZTogL3hzcmwvTnN2bi9pY3UvaWN1NGovc3JjL2NvbS9pYm0vaWN1L3RleHQvU3RyaW5nU2VhcmNoLmphdmEsdiAkIAogKiAkRGF0ZTogMjAwMi8xMi8wNSAwMjozNzoyOCAkIAogKiAkUmV2aXNpb246IDEuMTcgJAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICovCgpwYWNrYWdlIGNvbS5pYm0uaWN1LnRleHQ7CgppbXBvcnQgamF2YS50ZXh0LkNoYXJhY3Rlckl0ZXJhdG9yOwppbXBvcnQgamF2YS50ZXh0LlN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKaW1wb3J0IGNvbS5pYm0uaWN1LmxhbmcuVUNoYXJhY3RlcjsKaW1wb3J0IGNvbS5pYm0uaWN1LmltcGwuTm9ybWFsaXplckltcGw7CgovKioKICogPHA+CiAqIDxjb2RlPlN0cmluZ1NlYXJjaDwvY29kZT4gaXMgdGhlIGNvbmNyZXRlIHN1YmNsYXNzIG9mIAogKiA8Y29kZT5TZWFyY2hJdGVyYXRvcjwvY29kZT4gdGhhdCBwcm92aWRlcyBsYW5ndWFnZS1zZW5zaXRpdmUgdGV4dCBzZWFyY2hpbmcgCiAqIGJhc2VkIG9uIHRoZSBjb21wYXJpc29uIHJ1bGVzIGRlZmluZWQgaW4gYSB7QGxpbmsgUnVsZUJhc2VkQ29sbGF0b3J9IG9iamVjdC4KICogPC9wPgogKiA8cD4KICogPGNvZGU+U3RyaW5nU2VhcmNoPC9jb2RlPiB1c2VzIGEgdmVyc2lvbiBvZiB0aGUgZmFzdCBCb3llci1Nb29yZSBzZWFyY2gKICogYWxnb3JpdGhtIHRoYXQgaGFzIGJlZW4gYWRhcHRlZCB0byB3b3JrIHdpdGggdGhlIGxhcmdlIGNoYXJhY3RlciBzZXQgb2YKICogVW5pY29kZS4gUmVmZXIgdG8gCiAqIDxhIGhyZWY9aHR0cDovL29zcy5zb2Z0d2FyZS5pYm0uY29tL2ljdS9kb2NzL3BhcGVycy9lZmZpY2llbnRfdGV4dF9zZWFyY2hpbmdfaW5famF2YS5odG1sPgogKiAiRWZmaWNpZW50IFRleHQgU2VhcmNoaW5nIGluIEphdmEiPC9hPiwgcHVibGlzaGVkIGluIHRoZSAKICogPGk+SmF2YSBSZXBvcnQ8L2k+IG9uIEZlYnJ1YXJ5LCAxOTk5LCBmb3IgZnVydGhlciBpbmZvcm1hdGlvbiBvbiB0aGUgCiAqIGFsZ29yaXRobS4KICogPC9wPgogKiA8cD4KICogVXNlcnMgYXJlIGFsc28gc3Ryb25nbHkgZW5jb3VyYWdlZCB0byByZWFkIHRoZSBzZWN0aW9uIG9uIAogKiA8YSBocmVmPWh0dHA6Ly9vc3Muc29mdHdhcmUuaWJtLmNvbS9pY3UvdXNlcmd1aWRlL3NlYXJjaFN0cmluZy5odG1sPgogKiBTdHJpbmcgU2VhcmNoPC9hPiBhbmQgCiAqIDxhIGhyZWY9aHR0cDovL29zcy5zb2Z0d2FyZS5pYm0uY29tL2ljdS91c2VyZ3VpZGUvQ29sbGF0ZV9JbnRyby5odG1sPgogKiBDb2xsYXRpb248L2E+IGluIHRoZSB1c2VyIGd1aWRlIGJlZm9yZSBhdHRlbXB0aW5nIHRvIHVzZSB0aGlzIGNsYXNzLgogKiA8L3A+CiAqIDxwPgogKiBTdHJpbmcgc2VhcmNoaW5nIGdldHMgYWxpdHRsZSBjb21wbGljYXRlZCB3aGVuIGFjY2VudHMgYXJlIGVuY291bnRlcmVkIGF0CiAqIG1hdGNoIGJvdW5kYXJpZXMuIElmIGEgbWF0Y2ggaXMgZm91bmQgYW5kIGl0IGhhcyBwcmVjZWRpbmcgb3IgdHJhaWxpbmcgCiAqIGFjY2VudHMgbm90IHBhcnQgb2YgdGhlIG1hdGNoLCB0aGUgcmVzdWx0IHJldHVybmVkIHdpbGwgaW5jbHVkZSB0aGUgCiAqIHByZWNlZGluZyBhY2NlbnRzIHVwIHRvIHRoZSBmaXJzdCBiYXNlIGNoYXJhY3RlciwgaWYgdGhlIHBhdHRlcm4gc2VhcmNoZWQgCiAqIGZvciBzdGFydHMgYW4gYWNjZW50LiBMaWtld2lzZSwgCiAqIGlmIHRoZSBwYXR0ZXJuIGVuZHMgd2l0aCBhbiBhY2NlbnQsIGFsbCB0cmFpbGluZyBhY2NlbnRzIHVwIHRvIHRoZSBmaXJzdAogKiBiYXNlIGNoYXJhY3RlciB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSByZXN1bHQuCiAqIDwvcD4KICogPHA+CiAqIEZvciBleGFtcGxlLCBpZiBhIG1hdGNoIGlzIGZvdW5kIGluIHRhcmdldCB0ZXh0ICJhJiM5Mjt1MDMyNSYjOTI7dTAzMDAiIGZvciAKICogdGhlIHBhdHRlcm4KICogImEmIzkyO3UwMzI1IiwgdGhlIHJlc3VsdCByZXR1cm5lZCBieSBTdHJpbmdTZWFyY2ggd2lsbCBiZSB0aGUgaW5kZXggMCBhbmQKICogbGVuZ3RoIDMgJmx0OzAsIDMmZ3Q7LiBJZiBhIG1hdGNoIGlzIGZvdW5kIGluIHRoZSB0YXJnZXQgCiAqICJhJiM5Mjt1MDMyNSYjOTI7dTAzMDAiIAogKiBmb3IgdGhlIHBhdHRlcm4gIiYjOTI7dTAzMDAiLCB0aGVuIHRoZSByZXN1bHQgd2lsbCBiZSBpbmRleCAxIGFuZCBsZW5ndGggMiAKICogPDEsIDI+LgogKiA8L3A+CiAqIDxwPgogKiBJbiB0aGUgY2FzZSB3aGVyZSB0aGUgZGVjb21wb3NpdGlvbiBtb2RlIGlzIG9uIGZvciB0aGUgUnVsZUJhc2VkQ29sbGF0b3IsCiAqIGFsbCBtYXRjaGVzIHRoYXQgc3RhcnRzIG9yIGVuZHMgd2l0aCBhbiBhY2NlbnQgd2lsbCBoYXZlIGl0cyByZXN1bHRzIGluY2x1ZGUgCiAqIHByZWNlZGluZyBvciBmb2xsb3dpbmcgYWNjZW50cyByZXNwZWN0aXZlbHkuIEZvciBleGFtcGxlLCBpZiBwYXR0ZXJuICJhIiBpcwogKiBsb29rZWQgZm9yIGluIHRoZSB0YXJnZXQgdGV4dCAiJmFhY3V0ZTsmIzkyO3UwMzI1IiwgdGhlIHJlc3VsdCB3aWxsIGJlCiAqIGluZGV4IDAgYW5kIGxlbmd0aCAyICZsdDswLCAyJmd0Oy4KICogPC9wPgogKiA8cD4KICogVGhlIFN0cmluZ1NlYXJjaCBjbGFzcyBwcm92aWRlcyB0d28gb3B0aW9ucyB0byBoYW5kbGUgYWNjZW50IG1hdGNoaW5nIAogKiBkZXNjcmliZWQgYmVsb3c6CiAqIDwvcD4KICogPHA+CiAqIExldCBTJyBiZSB0aGUgc3ViLXN0cmluZyBvZiBhIHRleHQgc3RyaW5nIFMgYmV0d2VlbiB0aGUgb2Zmc2V0cyBzdGFydCBhbmQgCiAqIGVuZCAmbHQ7c3RhcnQsIGVuZCZndDsuCiAqIDxicj4KICogQSBwYXR0ZXJuIHN0cmluZyBQIG1hdGNoZXMgYSB0ZXh0IHN0cmluZyBTIGF0IHRoZSBvZmZzZXRzICZsdDtzdGFydCwgCiAqIGxlbmd0aCZndDsgCiAqIDxicj4KICogaWYKICogPHByZT4gCiAqIG9wdGlvbiAxLiBQIG1hdGNoZXMgc29tZSBjYW5vbmljYWwgZXF1aXZhbGVudCBzdHJpbmcgb2YgUycuIFN1cHBvc2UgdGhlIAogKiAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IgdXNlZCBmb3Igc2VhcmNoaW5nIGhhcyBhIGNvbGxhdGlvbiBzdHJlbmd0aCBvZiAKICogICAgICAgICAgIFRFUlRJQVJZLCBhbGwgYWNjZW50cyBhcmUgbm9uLWlnbm9yYWJsZS4gSWYgdGhlIHBhdHRlcm4gCiAqICAgICAgICAgICAiYSYjOTI7dTAzMDAiIGlzIHNlYXJjaGVkIGluIHRoZSB0YXJnZXQgdGV4dCAKICogICAgICAgICAgICJhJiM5Mjt1MDMyNSYjOTI7dTAzMDAiLCAKICogICAgICAgICAgIGEgbWF0Y2ggd2lsbCBiZSBmb3VuZCwgc2luY2UgdGhlIHRhcmdldCB0ZXh0IGlzIGNhbm9uaWNhbGx5IAogKiAgICAgICAgICAgZXF1aXZhbGVudCB0byAiYSYjOTI7dTAzMDAmIzkyO3UwMzI1IgogKiBvcHRpb24gMi4gUCBtYXRjaGVzIFMnIGFuZCBpZiBQIHN0YXJ0cyBvciBlbmRzIHdpdGggYSBjb21iaW5pbmcgbWFyaywgCiAqICAgICAgICAgICB0aGVyZSBleGlzdHMgbm8gbm9uLWlnbm9yYWJsZSBjb21iaW5pbmcgbWFyayBiZWZvcmUgb3IgYWZ0ZXIgU5IgCiAqICAgICAgICAgICBpbiBTIHJlc3BlY3RpdmVseS4gRm9sbG93aW5nIHRoZSBleGFtcGxlIGFib3ZlLCB0aGUgcGF0dGVybiAKICogICAgICAgICAgICJhJiM5Mjt1MDMwMCIgd2lsbCBub3QgZmluZCBhIG1hdGNoIGluICJhJiM5Mjt1MDMyNSYjOTI7dTAzMDAiLCAKICogICAgICAgICAgIHNpbmNlCiAqICAgICAgICAgICB0aGVyZSBleGlzdHMgYSBub24taWdub3JhYmxlIGFjY2VudCAnJiM5Mjt1MDMyNScgaW4gdGhlIG1pZGRsZSBvZiAKICogICAgICAgICAgICdhJyBhbmQgJyYjOTI7dTAzMDAnLiBFdmVuIHdpdGggYSB0YXJnZXQgdGV4dCBvZiAKICogICAgICAgICAgICJhJiM5Mjt1MDMwMCYjOTI7dTAzMjUiIGEgbWF0Y2ggd2lsbCBub3QgYmUgZm91bmQgYmVjYXVzZSBvZiB0aGUgCiAqICAgICAgICAgICBub24taWdub3JhYmxlIHRyYWlsaW5nIGFjY2VudCAmIzkyO3UwMzI1LgogKiA8L3ByZT4KICogT3B0aW9uIDIuIHdpbGwgYmUgdGhlIGRlZmF1bHQgbW9kZSBmb3IgZGVhbGluZyB3aXRoIGJvdW5kYXJ5IGFjY2VudHMgdW5sZXNzCiAqIHNwZWNpZmllZCB2aWEgdGhlIEFQSSBzZXRDYW5vbmljYWwoYm9vbGVhbikuCiAqIE9uZSByZXN0cmljdGlvbiBpcyB0byBiZSBub3RlZCBmb3Igb3B0aW9uIDEuIEN1cnJlbnRseSB0aGVyZSBhcmUgbm8gCiAqIGNvbXBvc2l0ZSBjaGFyYWN0ZXJzIHRoYXQgY29uc2lzdHMgb2YgYSBjaGFyYWN0ZXIgd2l0aCBjb21iaW5pbmcgY2xhc3MgPiAwIAogKiBiZWZvcmUgYSBjaGFyYWN0ZXIgd2l0aCBjb21iaW5pbmcgY2xhc3MgPT0gMC4gSG93ZXZlciwgaWYgc3VjaCBhIGNoYXJhY3RlciAKICogZXhpc3RzIGluIHRoZSBmdXR1cmUsIHRoZSBTdHJpbmdTZWFyY2ggbWF5IG5vdCB3b3JrIGNvcnJlY3RseSB3aXRoIG9wdGlvbiAxCiAqIHdoZW4gc3VjaCBjaGFyYWN0ZXJzIGFyZSBlbmNvdW50ZXJlZC4KICogPC9wPgogKiA8cD4KICogPHR0PlNlYXJjaEl0ZXJhdG9yPC90dD4gcHJvdmlkZXMgQVBJcyB0byBzcGVjaWZ5IHRoZSBzdGFydGluZyBwb3NpdGlvbiAKICogd2l0aGluIHRoZSB0ZXh0IHN0cmluZyB0byBiZSBzZWFyY2hlZCwgZS5nLiA8dHQ+c2V0SW5kZXg8L3R0PiwKICogPHR0PnByZWNlZGluZzwvdHQ+IGFuZCA8dHQ+Zm9sbG93aW5nPC90dD4uIFNpbmNlIHRoZSBzdGFydGluZyBwb3NpdGlvbiB3aWxsIAogKiBiZSBzZXQgYXMgaXQgaXMgc3BlY2lmaWVkLCBwbGVhc2UgdGFrZSBub3RlIHRoYXQgdGhlcmUgYXJlIHNvbWUgZGFuZ2Vyb3VzIAogKiBwb3NpdGlvbnMgd2hpY2ggdGhlIHNlYXJjaCBtYXkgcmVuZGVyIGluY29ycmVjdCByZXN1bHRzOgogKiA8dWw+CiAqIDxsaT4gVGhlIG1pZHN0IG9mIGEgc3Vic3RyaW5nIHRoYXQgcmVxdWlyZXMgZGVjb21wb3NpdGlvbi4KICogPGxpPiBJZiB0aGUgZm9sbG93aW5nIG1hdGNoIGlzIHRvIGJlIGZvdW5kLCB0aGUgcG9zaXRpb24gc2hvdWxkIG5vdCBiZSB0aGUKICogICAgICBzZWNvbmQgY2hhcmFjdGVyIHdoaWNoIHJlcXVpcmVzIHRvIGJlIHN3YXBwZWQgd2l0aCB0aGUgcHJlY2VkaW5nIAogKiAgICAgIGNoYXJhY3Rlci4gVmljZSB2ZXJzYSwgaWYgdGhlIHByZWNlZGluZyBtYXRjaCBpcyB0byBiZSBmb3VuZCwgCiAqICAgICAgcG9zaXRpb24gdG8gc2VhcmNoIGZyb20gc2hvdWxkIG5vdCBiZSB0aGUgZmlyc3QgY2hhcmFjdGVyIHdoaWNoIAogKiAgICAgIHJlcXVpcmVzIHRvIGJlIHN3YXBwZWQgd2l0aCB0aGUgbmV4dCBjaGFyYWN0ZXIuIEUuZyBjZXJ0YWluIFRoYWkgYW5kCiAqICAgICAgTGFvIGNoYXJhY3RlcnMgcmVxdWlyZSBzd2FwcGluZy4KICogPGxpPiBJZiBhIGZvbGxvd2luZyBwYXR0ZXJuIG1hdGNoIGlzIHRvIGJlIGZvdW5kLCBhbnkgcG9zaXRpb24gd2l0aGluIGEgCiAqICAgICAgY29udHJhY3Rpbmcgc2VxdWVuY2UgZXhjZXB0IHRoZSBmaXJzdCB3aWxsIGZhaWwuIFZpY2UgdmVyc2EgaWYgYSAKICogICAgICBwcmVjZWRpbmcgcGF0dGVybiBtYXRjaCBpcyB0byBiZSBmb3VuZCwgYSBpbnZhbGlkIHN0YXJ0aW5nIHBvaW50IAogKiAgICAgIHdvdWxkIGJlIGFueSBjaGFyYWN0ZXIgd2l0aGluIGEgY29udHJhY3Rpbmcgc2VxdWVuY2UgZXhjZXB0IHRoZSBsYXN0LgogKiA8L3VsPgogKiA8L3A+CiAqIDxwPgogKiBUaG91Z2ggY29sbGF0b3IgYXR0cmlidXRlcyB3aWxsIGJlIHRha2VuIGludG8gY29uc2lkZXJhdGlvbiB3aGlsZSAKICogcGVyZm9ybWluZyBtYXRjaGVzLCB0aGVyZSBhcmUgbm8gQVBJcyBwcm92aWRlZCBpbiBTdHJpbmdTZWFyY2ggZm9yIHNldHRpbmcgCiAqIGFuZCBnZXR0aW5nIHRoZSBhdHRyaWJ1dGVzLiBUaGVzZSBhdHRyaWJ1dGVzIGNhbiBiZSBzZXQgYnkgZ2V0dGluZyB0aGUgCiAqIGNvbGxhdG9yIGZyb20gPHR0PmdldENvbGxhdG9yPC90dD4gYW5kIHVzaW5nIHRoZSBBUElzIGluIAogKiA8dHQ+Y29tLmlibS5pY3UudGV4dC5Db2xsYXRvcjwvdHQ+LiBUbyB1cGRhdGUgU3RyaW5nU2VhcmNoIHRvIHRoZSBuZXcgCiAqIGNvbGxhdG9yIGF0dHJpYnV0ZXMsIDx0dD5yZXNldCgpPC90dD4gb3IgCiAqIDx0dD5zZXRDb2xsYXRvcihSdWxlQmFzZWRDb2xsYXRvcik8L3R0PiBoYXMgdG8gYmUgY2FsbGVkLgogKiA8L3A+CiAqIDxwPgogKiBDb25zdWx0IHRoZSAKICogPGEgaHJlZj1odHRwOi8vb3NzLnNvZnR3YXJlLmlibS5jb20vaWN1L3VzZXJndWlkZS9zZWFyY2hTdHJpbmcuaHRtbD4KICogU3RyaW5nIFNlYXJjaDwvYT4gdXNlciBndWlkZSBhbmQgdGhlIDxjb2RlPlNlYXJjaEl0ZXJhdG9yPC9jb2RlPiAKICogZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbiBhbmQgZXhhbXBsZXMgb2YgdXNlLgogKiA8L3A+CiAqIDxwPgogKiBUaGlzIGNsYXNzIGlzIG5vdCBzdWJjbGFzc2FibGUKICogPC9wPgogKiBAc2VlIFNlYXJjaEl0ZXJhdG9yCiAqIEBzZWUgUnVsZUJhc2VkQ29sbGF0b3IKICogQGF1dGhvciBMYXVyYSBXZXJuZXIsIHN5bndlZQogKiBAc3RhYmxlIElDVSAyLjAKICovCi8vIGludGVybmFsIG5vdGVzOiBhbGwgbWV0aG9kcyBkbyBub3QgZ3VhcmFudGVlIHRoZSBjb3JyZWN0IHN0YXR1cyBvZiB0aGUgCi8vIGNoYXJhY3Rlcml0ZXJhdG9yLiB0aGUgY2FsbGVyIGhhcyB0byBtYWludGFpbiB0aGUgb3JpZ2luYWwgaW5kZXggcG9zaXRpb24KLy8gaWYgbmVjZXNzYXJ5LiBtZXRob2RzIGNvdWxkIGNoYW5nZSB0aGUgaW5kZXggcG9zaXRpb24gYXMgaXQgZGVlbXMgZml0CnB1YmxpYyBmaW5hbCBjbGFzcyBTdHJpbmdTZWFyY2ggZXh0ZW5kcyBTZWFyY2hJdGVyYXRvcgp7CgkKCS8vIHB1YmxpYyBjb25zdHJ1Y3RvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCQogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyB0aGUgaXRlcmF0b3IgdG8gdXNlIHRoZSBsYW5ndWFnZS1zcGVjaWZpYyBydWxlcyBkZWZpbmVkIGluIAogICAgICogdGhlIGFyZ3VtZW50IGNvbGxhdG9yIHRvIHNlYXJjaCBmb3IgYXJndW1lbnQgcGF0dGVybiBpbiB0aGUgYXJndW1lbnQgCiAgICAgKiB0YXJnZXQgdGV4dC4gVGhlIGFyZ3VtZW50IGJyZWFraXRlciBpcyB1c2VkIHRvIGRlZmluZSBsb2dpY2FsIG1hdGNoZXMuCiAgICAgKiBTZWUgc3VwZXIgY2xhc3MgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBkZXRhaWxzIG9uIHRoZSB1c2Ugb2YgdGhlIHRhcmdldCAKICAgICAqIHRleHQgYW5kIEJyZWFrSXRlcmF0b3IuCiAgICAgKiBAcGFyYW0gcGF0dGVybiB0ZXh0IHRvIGxvb2sgZm9yLgogICAgICogQHBhcmFtIHRhcmdldCB0YXJnZXQgdGV4dCB0byBzZWFyY2ggZm9yIHBhdHRlcm4uIAogICAgICogQHBhcmFtIGNvbGxhdG9yIFJ1bGVCYXNlZENvbGxhdG9yIHRoYXQgZGVmaW5lcyB0aGUgbGFuZ3VhZ2UgcnVsZXMKICAgICAqIEBwYXJhbSBicmVha2VyIEEge0BsaW5rIEJyZWFrSXRlcmF0b3J9IHRoYXQgaXMgdXNlZCB0byBkZXRlcm1pbmUgdGhlIAogICAgICogICAgICAgICAgICAgICAgYm91bmRhcmllcyBvZiBhIGxvZ2ljYWwgbWF0Y2guIFRoaXMgYXJndW1lbnQgY2FuIGJlIG51bGwuCiAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB0aHJvd24gd2hlbiBhcmd1bWVudCB0YXJnZXQgaXMgbnVsbCwKICAgICAqICAgICAgICAgICAgb3Igb2YgbGVuZ3RoIDAKICAgICAqIEBzZWUgQnJlYWtJdGVyYXRvcgogICAgICogQHNlZSBSdWxlQmFzZWRDb2xsYXRvcgogICAgICogQHNlZSBTZWFyY2hJdGVyYXRvcgogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmdTZWFyY2goU3RyaW5nIHBhdHRlcm4sIENoYXJhY3Rlckl0ZXJhdG9yIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IgY29sbGF0b3IsIEJyZWFrSXRlcmF0b3IgYnJlYWtpdGVyKSAKICAgIHsKICAgICAgICBzdXBlcih0YXJnZXQsIGJyZWFraXRlcik7CiAgICAgICAgbV90ZXh0QmVnaW5PZmZzZXRfID0gdGFyZ2V0VGV4dC5nZXRCZWdpbkluZGV4KCk7CiAgICAgICAgbV90ZXh0TGltaXRPZmZzZXRfID0gdGFyZ2V0VGV4dC5nZXRFbmRJbmRleCgpOwogICAgICAgIG1fY29sbGF0b3JfID0gY29sbGF0b3I7CiAgICAgICAgbV9jb2xFSXRlcl8gPSBtX2NvbGxhdG9yXy5nZXRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IodGFyZ2V0KTsKICAgICAgICBtX3V0aWxDb2xFSXRlcl8gPSBjb2xsYXRvci5nZXRDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoIiIpOwogICAgICAgIG1fY2VNYXNrXyA9IGdldE1hc2sobV9jb2xsYXRvcl8uZ2V0U3RyZW5ndGgoKSk7CiAgICAgICAgbV9pc0Nhbm9uaWNhbE1hdGNoXyA9IGZhbHNlOwogICAgICAgIG1fcGF0dGVybl8gPSBuZXcgUGF0dGVybihwYXR0ZXJuKTsKICAgICAgICBtX21hdGNoZWRJbmRleF8gPSBET05FOwogICAgICAgIAogICAgICAgIGluaXRpYWxpemUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEluaXRpYWxpemVzIHRoZSBpdGVyYXRvciB0byB1c2UgdGhlIGxhbmd1YWdlLXNwZWNpZmljIHJ1bGVzIGRlZmluZWQgaW4gCiAgICAgKiB0aGUgYXJndW1lbnQgY29sbGF0b3IgdG8gc2VhcmNoIGZvciBhcmd1bWVudCBwYXR0ZXJuIGluIHRoZSBhcmd1bWVudCAKICAgICAqIHRhcmdldCB0ZXh0LiBObyBCcmVha0l0ZXJhdG9ycyBhcmUgc2V0IHRvIHRlc3QgZm9yIGxvZ2ljYWwgbWF0Y2hlcy4KICAgICAqIEBwYXJhbSBwYXR0ZXJuIHRleHQgdG8gbG9vayBmb3IuCiAgICAgKiBAcGFyYW0gdGFyZ2V0IHRhcmdldCB0ZXh0IHRvIHNlYXJjaCBmb3IgcGF0dGVybi4gCiAgICAgKiBAcGFyYW0gY29sbGF0b3IgUnVsZUJhc2VkQ29sbGF0b3IgdGhhdCBkZWZpbmVzIHRoZSBsYW5ndWFnZSBydWxlcwogICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gdGhyb3duIHdoZW4gYXJndW1lbnQgdGFyZ2V0IGlzIG51bGwsCiAgICAgKiAgICAgICAgICAgIG9yIG9mIGxlbmd0aCAwCiAgICAgKiBAc2VlIFJ1bGVCYXNlZENvbGxhdG9yCiAgICAgKiBAc2VlIFNlYXJjaEl0ZXJhdG9yCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgcHVibGljIFN0cmluZ1NlYXJjaChTdHJpbmcgcGF0dGVybiwgQ2hhcmFjdGVySXRlcmF0b3IgdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvciBjb2xsYXRvcikgCiAgICB7CiAgICAgICAgdGhpcyhwYXR0ZXJuLCB0YXJnZXQsIGNvbGxhdG9yLCBCcmVha0l0ZXJhdG9yLmdldENoYXJhY3Rlckluc3RhbmNlKCkpOwogICAgfQoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgdGhlIGl0ZXJhdG9yIHRvIHVzZSB0aGUgbGFuZ3VhZ2Utc3BlY2lmaWMgcnVsZXMgYW5kIAogICAgICogYnJlYWsgaXRlcmF0b3IgcnVsZXMgZGVmaW5lZCBpbiB0aGUgYXJndW1lbnQgbG9jYWxlIHRvIHNlYXJjaCBmb3IgCiAgICAgKiBhcmd1bWVudCBwYXR0ZXJuIGluIHRoZSBhcmd1bWVudCB0YXJnZXQgdGV4dC4gCiAgICAgKiBTZWUgc3VwZXIgY2xhc3MgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBkZXRhaWxzIG9uIHRoZSB1c2Ugb2YgdGhlIHRhcmdldCAKICAgICAqIHRleHQgYW5kIEJyZWFrSXRlcmF0b3IuCiAgICAgKiBAcGFyYW0gcGF0dGVybiB0ZXh0IHRvIGxvb2sgZm9yLgogICAgICogQHBhcmFtIHRhcmdldCB0YXJnZXQgdGV4dCB0byBzZWFyY2ggZm9yIHBhdHRlcm4uIAogICAgICogQHBhcmFtIGxvY2FsZSBsb2NhbGUgdG8gdXNlIGZvciBsYW5ndWFnZSBhbmQgYnJlYWsgaXRlcmF0b3IgcnVsZXMKICAgICAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHRocm93biB3aGVuIGFyZ3VtZW50IHRhcmdldCBpcyBudWxsLAogICAgICogICAgICAgICAgICBvciBvZiBsZW5ndGggMC4gQ2xhc3NDYXN0RXhjZXB0aW9uIHRocm93biBpZiB0aGUgY29sbGF0b3IgZm9yIAogICAgICogICAgICAgICAgICB0aGUgc3BlY2lmaWVkIGxvY2FsZSBpcyBub3QgYSBSdWxlQmFzZWRDb2xsYXRvci4KICAgICAqIEBzZWUgQnJlYWtJdGVyYXRvcgogICAgICogQHNlZSBSdWxlQmFzZWRDb2xsYXRvcgogICAgICogQHNlZSBTZWFyY2hJdGVyYXRvcgogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmdTZWFyY2goU3RyaW5nIHBhdHRlcm4sIENoYXJhY3Rlckl0ZXJhdG9yIHRhcmdldCwgTG9jYWxlIGxvY2FsZSkKICAgIHsKICAgICAgICB0aGlzKHBhdHRlcm4sIHRhcmdldCwgKFJ1bGVCYXNlZENvbGxhdG9yKUNvbGxhdG9yLmdldEluc3RhbmNlKGxvY2FsZSksCiAgICAgICAgICAgICBCcmVha0l0ZXJhdG9yLmdldENoYXJhY3Rlckluc3RhbmNlKGxvY2FsZSkpOwogICAgfQoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZXMgdGhlIGl0ZXJhdG9yIHRvIHVzZSB0aGUgbGFuZ3VhZ2Utc3BlY2lmaWMgcnVsZXMgYW5kIAogICAgICogYnJlYWsgaXRlcmF0b3IgcnVsZXMgZGVmaW5lZCBpbiB0aGUgZGVmYXVsdCBsb2NhbGUgdG8gc2VhcmNoIGZvciAKICAgICAqIGFyZ3VtZW50IHBhdHRlcm4gaW4gdGhlIGFyZ3VtZW50IHRhcmdldCB0ZXh0LiAKICAgICAqIFNlZSBzdXBlciBjbGFzcyBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGRldGFpbHMgb24gdGhlIHVzZSBvZiB0aGUgdGFyZ2V0IAogICAgICogdGV4dCBhbmQgQnJlYWtJdGVyYXRvci4KICAgICAqIEBwYXJhbSBwYXR0ZXJuIHRleHQgdG8gbG9vayBmb3IuCiAgICAgKiBAcGFyYW0gdGFyZ2V0IHRhcmdldCB0ZXh0IHRvIHNlYXJjaCBmb3IgcGF0dGVybi4gCiAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB0aHJvd24gd2hlbiBhcmd1bWVudCB0YXJnZXQgaXMgbnVsbCwKICAgICAqICAgICAgICAgICAgb3Igb2YgbGVuZ3RoIDAuIENsYXNzQ2FzdEV4Y2VwdGlvbiB0aHJvd24gaWYgdGhlIGNvbGxhdG9yIGZvciAKICAgICAqICAgICAgICAgICAgdGhlIGRlZmF1bHQgbG9jYWxlIGlzIG5vdCBhIFJ1bGVCYXNlZENvbGxhdG9yLgogICAgICogQHNlZSBCcmVha0l0ZXJhdG9yCiAgICAgKiBAc2VlIFJ1bGVCYXNlZENvbGxhdG9yCiAgICAgKiBAc2VlIFNlYXJjaEl0ZXJhdG9yCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgcHVibGljIFN0cmluZ1NlYXJjaChTdHJpbmcgcGF0dGVybiwgU3RyaW5nIHRhcmdldCkgCiAgICB7CiAgICAgICAgdGhpcyhwYXR0ZXJuLCBuZXcgU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3IodGFyZ2V0KSwKICAgICAgICAgICAgIChSdWxlQmFzZWRDb2xsYXRvcilDb2xsYXRvci5nZXRJbnN0YW5jZSgpLAogICAgICAgICAgICAgQnJlYWtJdGVyYXRvci5nZXRDaGFyYWN0ZXJJbnN0YW5jZSgpKTsKICAgIH0KCiAgICAvLyBwdWJsaWMgZ2V0dGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHN0cmVuZ3RoIHByb3BlcnR5IG9mIHRoZSBSdWxlQmFzZWRDb2xsYXRvciB1c2VkIGluIHNlYXJjaGluZy4gCiAgICAgKiBTZWUgdGhlIFJ1bGVCYXNlZENvbGxhdG9yIGNsYXNzIGRvY3VtZW50YXRpb24gZm9yIGEgZGVzY3JpcHRpb24gb2YgdGhlCiAgICAgKiBzdHJlbmd0aCBwcm9wZXJ0eS4KICAgICAqIEByZXR1cm4gdGhlIHN0cmVuZ3RoIHByb3BlcnR5IG9mIHRoZSBSdWxlQmFzZWRDb2xsYXRvciB1c2VkIGluIHNlYXJjaGluZwogICAgICogQHNlZSBSdWxlQmFzZWRDb2xsYXRvcgogICAgICogQHNlZSAjc2V0U3RyZW5ndGgKICAgICAqIEBzZWUgI2dldENvbGxhdG9yCiAgICAgKiBAb2Jzb2xldGUgSUNVIDIuMi4gVXNlIHRoaXMuZ2V0Q29sbGF0b3IoKS5nZXRTdHJlbmd0aCgpIGluc3RlYWQgc2luY2UgaXQKICAgICAqICAgICAgICAgICB3aWxsIGJlIHJlbW92ZWQgaW4gdGhhdCByZWxlYXNlLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFN0cmVuZ3RoKCkgewogICAgICAgIHJldHVybiBtX2NvbGxhdG9yXy5nZXRTdHJlbmd0aCgpOwogICAgfQogICAgCiAgICAvKioKCSAqIDxwPgogICAgICogR2V0cyB0aGUgUnVsZUJhc2VkQ29sbGF0b3IgdXNlZCBmb3IgdGhlIGxhbmd1YWdlIHJ1bGVzLgogICAgICogPC9wPgoJICogPHA+CiAgICAgKiBTaW5jZSBTdHJpbmdTZWFyY2ggZGVwZW5kcyBvbiB0aGUgcmV0dXJuZWQgUnVsZUJhc2VkQ29sbGF0b3IsIGFueSAKCSAqIGNoYW5nZXMgdG8gdGhlIFJ1bGVCYXNlZENvbGxhdG9yIHJlc3VsdCBzaG91bGQgZm9sbG93IHdpdGggYSBjYWxsIHRvIAoJICogZWl0aGVyIFN0cmluZ1NlYXJjaC5yZXNldCgpIG9yIAoJICogU3RyaW5nU2VhcmNoLnNldENvbGxhdG9yKFJ1bGVCYXNlZENvbGxhdG9yKSB0byBlbnN1cmUgdGhlIGNvcnJlY3QgCgkgKiBzZWFyY2ggYmVoYXZpb3VyLgogICAgICogPC9wPgoJICogQHJldHVybiBSdWxlQmFzZWRDb2xsYXRvciB1c2VkIGJ5IHRoaXMgU3RyaW5nU2VhcmNoCiAgICAgKiBAc2VlIFJ1bGVCYXNlZENvbGxhdG9yCiAgICAgKiBAc2VlICNzZXRDb2xsYXRvcgogICAgICogQHN0YWJsZSBJQ1UgMi4wCgkgKi8KICAgIHB1YmxpYyBSdWxlQmFzZWRDb2xsYXRvciBnZXRDb2xsYXRvcigpIAogICAgewogICAgICAgIHJldHVybiBtX2NvbGxhdG9yXzsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwYXR0ZXJuIGZvciB3aGljaCBTdHJpbmdTZWFyY2ggaXMgc2VhcmNoaW5nIGZvci4KICAgICAqIEByZXR1cm4gdGhlIHBhdHRlcm4gc2VhcmNoZWQgZm9yCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgcHVibGljIFN0cmluZyBnZXRQYXR0ZXJuKCkgCiAgICB7CiAgICAgICAgcmV0dXJuIG1fcGF0dGVybl8udGFyZ2V0VGV4dDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGluZGV4IGluIHRoZSB0YXJnZXQgdGV4dCB3aGVyZSB0aGUgaXRlcmF0b3IgaXMgY3VycmVudGx5IAogICAgICogcG9zaXRpb25lZCBhdC4gCiAgICAgKiBJZiB0aGUgaXRlcmF0aW9uIGhhcyBnb25lIHBhc3QgdGhlIGVuZCBvZiB0aGUgdGFyZ2V0IHRleHQgb3IgcGFzdCAKICAgICAqIHRoZSBiZWdpbm5pbmcgZm9yIGEgYmFja3dhcmRzIHNlYXJjaCwge0BsaW5rICNET05FfSBpcyByZXR1cm5lZC4KICAgICAqIEByZXR1cm4gaW5kZXggaW4gdGhlIHRhcmdldCB0ZXh0IHdoZXJlIHRoZSBpdGVyYXRvciBpcyBjdXJyZW50bHkgCiAgICAgKiAgICAgICAgIHBvc2l0aW9uZWQgYXQKICAgICAqIEBkcmFmdCBJQ1UgMi4yCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0SW5kZXgoKSAKICAgIHsKICAgICAgICBpbnQgcmVzdWx0ID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CiAgICAgICAgaWYgKGlzT3V0T2ZCb3VuZHMobV90ZXh0QmVnaW5PZmZzZXRfLCBtX3RleHRMaW1pdE9mZnNldF8sIHJlc3VsdCkpIHsKICAgICAgICAgICAgcmV0dXJuIERPTkU7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIGNhbm9uaWNhbCBtYXRjaGVzIChvcHRpb24gMSwgYXMgZGVzY3JpYmVkIGluIHRoZSAKICAgICAqIGNsYXNzIGRvY3VtZW50YXRpb24pIGlzIHNldC4KICAgICAqIFNlZSBzZXRDYW5vbmljYWwoYm9vbGVhbikgZm9yIG1vcmUgaW5mb3JtYXRpb24uCiAgICAgKiBAc2VlICNzZXRDYW5vbmljYWwKICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBjYW5vbmljYWwgbWF0Y2hlcyBpcyBzZXQsIGZhbHNlIG90aGVyd2lzZQogICAgICogQGRyYWZ0IElDVSAyLjIKICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNDYW5vbmljYWwoKSAKICAgIHsKICAgICAgICByZXR1cm4gbV9pc0Nhbm9uaWNhbE1hdGNoXzsKICAgIH0KICAgIAogICAgLy8gcHVibGljIHNldHRlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIAogICAgLyoqCiAgICAgKiA8cD4KICAgICAqIFNldHMgdGhlIHN0cmVuZ3RoIHByb3BlcnR5IG9mIHRoZSBSdWxlQmFzZWRDb2xsYXRvciB1c2VkIGZvciBzZWFyY2hpbmcuCiAgICAgKiBTZWUgdGhlIENvbGxhdG9yIGRvY3VtZW50YXRpb24gZm9yIGEgZGVzY3JpcHRpb24gb2YgdGhlIHN0cmVuZ3Rocy4KICAgICAqIDwvcD4KICAgICAqIEBvYnNvbGV0ZSBJQ1UgMi4yLiBVc2UgdGhpcy5nZXRDb2xsYXRvcigpLnNldFN0cmVuZ3RoKGludCkgaW5zdGVhZCBzaW5jZQogICAgICogICAgICAgICAgIGl0IHdpbGwgYmUgcmVtb3ZlZCBpbiB0aGF0IHJlbGVhc2UuCiAgICAgKiAgICAgICAgICAgICBBZnRlciB3aGljaCBTdHJpbmdTZWFyY2gucmVzZXQoKSAKICAgICAqICAgICAgICAgICAgIG9yIFN0cmluZ1NlYXJjaC5zZXRDb2xsYXRvcih0aGlzLmdldENvbGxhdG9yKCkpIHNob3VsZCBiZQogICAgICogICAgICAgICAgICAgY2FsbGVkIHRvIHVwZGF0ZSBTdHJpbmdTZWFyY2guXQogICAgICogQHNlZSBDb2xsYXRvcgogICAgICogQHNlZSBDb2xsYXRvciNQUklNQVJZCiAgICAgKiBAc2VlIENvbGxhdG9yI1NFQ09OREFSWQogICAgICogQHNlZSBDb2xsYXRvciNURVJUSUFSWQogICAgICogQHNlZSBDb2xsYXRvciNRVUFURVJOQVJZCiAgICAgKiBAc2VlIENvbGxhdG9yI0lERU5USUNBTAogICAgICogQHNlZSAjc2V0Q29sbGF0b3IKICAgICAqIEBzZWUgI2dldENvbGxhdG9yCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldFN0cmVuZ3RoKGludCBuZXdTdHJlbmd0aCkgCiAgICB7CiAgICAgICAgLy8gRHVlIHRvIGEgYnVnICg/KSBpbiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IsIHdlIG11c3Qgc2V0IHRoZQogICAgICAgIC8vIGNvbGxhdG9yJ3Mgc3RyZW5ndGggYXMgd2VsbCwgc2luY2UgdGhlIGl0ZXJhdG9yIGlzIGdvaW5nIHRvCiAgICAgICAgLy8gbWFzayBvdXQgdGhlIHBvcnRpb25zIG9mIHRoZSBjb2xsYXRpb24gZWxlbWVudCB0aGF0IGFyZSBub3QKICAgICAgICAvLyByZWxldmFudCBmb3IgdGhlIGNvbGxhdG9yJ3MgY3VycmVudCBzdHJlbmd0aCBzZXR0aW5nCiAgICAgICAgLy8gTm90ZSB0aGF0IHRoaXMgbWFrZXMgaXQgaW1wb3NzaWJsZSB0byBzaGFyZSBhIENvbGxhdG9yIGFtb25nCiAgICAgICAgLy8gbXVsdGlwbGUgU3RyaW5nU2VhcmNoIG9iamVjdHMgaWYgeW91IGFkanVzdCBTdHJlbmd0aCBzZXR0aW5ncy4KICAgICAgICBtX2NvbGxhdG9yXy5zZXRTdHJlbmd0aChuZXdTdHJlbmd0aCk7CiAgICAgICAgaW5pdGlhbGl6ZSgpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIDxwPgogICAgICogU2V0cyB0aGUgUnVsZUJhc2VkQ29sbGF0b3IgdG8gYmUgdXNlZCBmb3IgbGFuZ3VhZ2Utc3BlY2lmaWMgc2VhcmNoaW5nLgogICAgICogPC9wPgogICAgICogPHA+CiAgICAgKiBUaGlzIG1ldGhvZCBjYXVzZXMgaW50ZXJuYWwgZGF0YSBzdWNoIGFzIEJveWVyLU1vb3JlIHNoaWZ0IHRhYmxlcwogICAgICogdG8gYmUgcmVjYWxjdWxhdGVkLCBidXQgdGhlIGl0ZXJhdG9yJ3MgcG9zaXRpb24gaXMgdW5jaGFuZ2VkLgogICAgICogPC9wPgogICAgICogQHBhcmFtIGNvbGxhdG9yIHRvIHVzZSBmb3IgdGhpcyBTdHJpbmdTZWFyY2gKICAgICAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHRocm93biB3aGVuIGNvbGxhdG9yIGlzIG51bGwKICAgICAqIEBzZWUgI2dldENvbGxhdG9yCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0Q29sbGF0b3IoUnVsZUJhc2VkQ29sbGF0b3IgY29sbGF0b3IpIAogICAgewogICAgCWlmIChjb2xsYXRvciA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkNvbGxhdG9yIGNhbiBub3QgYmUgbnVsbCIpOwogICAgICAgIH0KICAgICAgICBtX2NvbGxhdG9yXyA9IGNvbGxhdG9yOwogICAgICAgIG1fY2VNYXNrXyA9IGdldE1hc2sobV9jb2xsYXRvcl8uZ2V0U3RyZW5ndGgoKSk7CiAgICAgICAgLy8gaWYgc3RhdHVzIGlzIGEgZmFpbHVyZSwgdWNvbF9nZXRBdHRyaWJ1dGUgcmV0dXJucyBVQ09MX0RFRkFVTFQKICAgICAgICBpbml0aWFsaXplKCk7CiAgICAgICAgbV9jb2xFSXRlcl8uc2V0Q29sbGF0b3IobV9jb2xsYXRvcl8pOwogICAgICAgIG1fdXRpbENvbEVJdGVyXy5zZXRDb2xsYXRvcihtX2NvbGxhdG9yXyk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogPHA+CiAgICAgKiBTZXQgdGhlIHBhdHRlcm4gdG8gc2VhcmNoIGZvci4gIAogICAgICogPC9wPgogICAgICogPHA+CiAgICAgKiBUaGlzIG1ldGhvZCBjYXVzZXMgaW50ZXJuYWwgZGF0YSBzdWNoIGFzIEJveWVyLU1vb3JlIHNoaWZ0IHRhYmxlcwogICAgICogdG8gYmUgcmVjYWxjdWxhdGVkLCBidXQgdGhlIGl0ZXJhdG9yJ3MgcG9zaXRpb24gaXMgdW5jaGFuZ2VkLgogICAgICogPC9wPgogICAgICogQHBhcmFtIHBhdHRlcm4gZm9yIHNlYXJjaGluZwogICAgICogQHNlZSAjZ2V0UGF0dGVybgogICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gdGhyb3duIGlmIHBhdHRlcm4gaXMgbnVsbCBvciBvZgogICAgICogCQkJICBsZW5ndGggMAogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldFBhdHRlcm4oU3RyaW5nIHBhdHRlcm4pIAogICAgewogICAgCWlmIChwYXR0ZXJuID09IG51bGwgfHwgcGF0dGVybi5sZW5ndGgoKSA8PSAwKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgIAkJIlBhdHRlcm4gdG8gc2VhcmNoIGZvciBjYW4gbm90IGJlIG51bGwgb3Igb2YgbGVuZ3RoIDAiKTsKICAgICAgICB9CiAgICAgICAgbV9wYXR0ZXJuXy50YXJnZXRUZXh0ID0gcGF0dGVybjsKICAgICAgICBpbml0aWFsaXplKCk7CiAgICB9CiAgICAKICAgIC8qKgogCSAqIFNldCB0aGUgdGFyZ2V0IHRleHQgdG8gYmUgc2VhcmNoZWQuIFRleHQgaXRlcmF0aW9uIHdpbGwgaGVuY2UgYmVnaW4gYXQgCiAgICAgKiB0aGUgc3RhcnQgb2YgdGhlIHRleHQgc3RyaW5nLiBUaGlzIG1ldGhvZCBpcyB1c2VmdWwgaWYgeW91IHdhbnQgdG8gCiAgICAgKiByZS11c2UgYW4gaXRlcmF0b3IgdG8gc2VhcmNoIHdpdGhpbiBhIGRpZmZlcmVudCBib2R5IG9mIHRleHQuCiAgICAgKiBAcGFyYW0gdGV4dCBuZXcgdGV4dCBpdGVyYXRvciB0byBsb29rIGZvciBtYXRjaCwgCiAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB0aHJvd24gd2hlbiB0ZXh0IGlzIG51bGwgb3IgaGFzCiAgICAgKiAgICAgICAgICAgIDAgbGVuZ3RoCiAgICAgKiBAc2VlICNnZXRUYXJnZXQKCSAqIEBkcmFmdCBJQ1UgMi4yCgkgKi8KCXB1YmxpYyB2b2lkIHNldFRhcmdldChDaGFyYWN0ZXJJdGVyYXRvciB0ZXh0KQoJewoJCXN1cGVyLnNldFRhcmdldCh0ZXh0KTsKICAgICAgICBtX3RleHRCZWdpbk9mZnNldF8gPSB0YXJnZXRUZXh0LmdldEJlZ2luSW5kZXgoKTsKICAgICAgICBtX3RleHRMaW1pdE9mZnNldF8gPSB0YXJnZXRUZXh0LmdldEVuZEluZGV4KCk7CiAgICAgICAgbV9jb2xFSXRlcl8uc2V0VGV4dCh0YXJnZXRUZXh0KTsKCX0KICAgIAogICAgLyoqCgkgKiA8cD4KICAgICAqIFNldHMgdGhlIHBvc2l0aW9uIGluIHRoZSB0YXJnZXQgdGV4dCB3aGljaCB0aGUgbmV4dCBzZWFyY2ggd2lsbCBzdGFydCAKICAgICAqIGZyb20gdG8gdGhlIGFyZ3VtZW50LiBUaGlzIG1ldGhvZCBjbGVhcnMgYWxsIHByZXZpb3VzIHN0YXRlcy4KICAgICAqIDwvcD4KICAgICAqIDxwPgogICAgICogVGhpcyBtZXRob2QgdGFrZXMgdGhlIGFyZ3VtZW50IHBvc2l0aW9uIGFuZCBzZXRzIHRoZSBwb3NpdGlvbiBpbiB0aGUgCiAgICAgKiB0YXJnZXQgdGV4dCBhY2NvcmRpbmdseSwgd2l0aG91dCBjaGVja2luZyBpZiBwb3NpdGlvbiBpcyBwb2ludGluZyB0byBhIAogICAgICogdmFsaWQgc3RhcnRpbmcgcG9pbnQgdG8gYmVnaW4gc2VhcmNoaW5nLgogICAgICogPC9wPgogICAgICogPHA+CiAgICAgKiBTZWFyY2ggcG9zaXRpb25zIHRoYXQgbWF5IHJlbmRlciBpbmNvcnJlY3QgcmVzdWx0cyBhcmUgaGlnaGxpZ2h0ZWQgaW4gCiAgICAgKiB0aGUgY2xhc3MgZG9jdW1lbnRhdGlvbi4KICAgICAqIDwvcD4KICAgICAqIEBwYXJhbSBwb3NpdGlvbiBpbmRleCB0byBzdGFydCBuZXh0IHNlYXJjaCBmcm9tLgogICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHRocm93biBpZiBhcmd1bWVudCBwb3NpdGlvbiBpcyBvdXQKICAgICAqICAgICAgICAgICAgb2YgdGhlIHRhcmdldCB0ZXh0IHJhbmdlLgogICAgICogQHNlZSAjZ2V0SW5kZXgKICAgICAqIEBkcmFmdCBJQ1UgMi4yCgkgKi8KCXB1YmxpYyB2b2lkIHNldEluZGV4KGludCBwb3NpdGlvbikKCXsKCQlzdXBlci5zZXRJbmRleChwb3NpdGlvbik7CiAgICAgICAgbV9tYXRjaGVkSW5kZXhfID0gRE9ORTsKICAgICAgICBtX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldChwb3NpdGlvbik7Cgl9CgkKCS8qKgoJICogPHA+CiAgICAgKiBTZXQgdGhlIGNhbm9uaWNhbCBtYXRjaCBtb2RlLiBTZWUgY2xhc3MgZG9jdW1lbnRhdGlvbiBmb3IgZGV0YWlscy4KICAgICAqIFRoZSBkZWZhdWx0IHNldHRpbmcgZm9yIHRoaXMgcHJvcGVydHkgaXMgZmFsc2UuCiAgICAgKiA8L3A+CgkgKiBAcGFyYW0gYWxsb3dDYW5vbmljYWwgZmxhZyBpbmRpY2F0b3IgaWYgY2Fub25pY2FsIG1hdGNoZXMgYXJlIGFsbG93ZWQKICAgICAqIEBzZWUgI2lzQ2Fub25pY2FsCgkgKiBAZHJhZnQgSUNVIDIuMgoJICovCglwdWJsaWMgdm9pZCBzZXRDYW5vbmljYWwoYm9vbGVhbiBhbGxvd0Nhbm9uaWNhbCkKCXsKCQltX2lzQ2Fub25pY2FsTWF0Y2hfID0gYWxsb3dDYW5vbmljYWw7CgkJaWYgKG1faXNDYW5vbmljYWxNYXRjaF8gPT0gdHJ1ZSkgewoJCQlpZiAobV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXyA9PSBudWxsKSB7CgkJCQltX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfID0gbmV3IFN0cmluZ0J1ZmZlcigpOwoJCQl9CgkJCWVsc2UgewoJCQkJbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5kZWxldGUoMCwgCgkJCQkJCQkJCQkJbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5sZW5ndGgoKSk7CgkJCX0KCQkJaWYgKG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18gPT0gbnVsbCkgewoJCQkJbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXyA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKCQkJfQoJCQllbHNlIHsKCQkJCW1fY2Fub25pY2FsU3VmZml4QWNjZW50c18uZGVsZXRlKDAsIAoJCQkJCQkJCQkJCW1fY2Fub25pY2FsU3VmZml4QWNjZW50c18ubGVuZ3RoKCkpOwoJCQl9CgkJfQoJfQoJCgkvLyBwdWJsaWMgbWlzY2VsbGFuZW91cyBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkKCS8qKiAKCSAqIDxwPgogICAgICogUmVzZXRzIHRoZSBzZWFyY2ggaXRlcmF0aW9uLiBBbGwgcHJvcGVydGllcyB3aWxsIGJlIHJlc2V0IHRvIHRoZSAKICAgICAqIGRlZmF1bHQgdmFsdWUuCiAgICAgKiA8L3A+CiAgICAgKiA8cD4KICAgICAqIFNlYXJjaCB3aWxsIGJlZ2luIGF0IHRoZSBzdGFydCBvZiB0aGUgdGFyZ2V0IHRleHQgaWYgYSBmb3J3YXJkIGl0ZXJhdGlvbiAKICAgICAqIGlzIGluaXRpYXRlZCBiZWZvcmUgYSBiYWNrd2FyZHMgaXRlcmF0aW9uLiBPdGhlcndpc2UgaWYgYSAKICAgICAqIGJhY2t3YXJkcyBpdGVyYXRpb24gaXMgaW5pdGlhdGVkIGJlZm9yZSBhIGZvcndhcmRzIGl0ZXJhdGlvbiwgdGhlIHNlYXJjaCAKICAgICAqIHdpbGwgYmVnaW4gYXQgdGhlIGVuZCBvZiB0aGUgdGFyZ2V0IHRleHQuCiAgICAgKiA8L3A+CiAgICAgKiA8cD4KICAgICAqIENhbm9uaWNhbCBtYXRjaCBvcHRpb24gd2lsbCBiZSByZXNldCB0byBmYWxzZSwgaWUgYW4gZXhhY3QgbWF0Y2guCiAgICAgKiA8L3A+CgkgKiBAZHJhZnQgSUNVIDIuMgoJICovCglwdWJsaWMgdm9pZCByZXNldCgpCgl7CgkJLy8gcmVzZXQgaXMgc2V0dGluZyB0aGUgYXR0cmlidXRlcyB0aGF0IGFyZSBhbHJlYWR5IGluIHN0cmluZyBzZWFyY2gsIAoJCS8vIGhlbmNlIGFsbCBhdHRyaWJ1dGVzIGluIHRoZSBjb2xsYXRvciBzaG91bGQgYmUgcmV0cmlldmVkIHdpdGhvdXQgYW55IAoJCS8vIHByb2JsZW1zCgkJc3VwZXIucmVzZXQoKTsKICAgICAgICBtX2lzQ2Fub25pY2FsTWF0Y2hfID0gZmFsc2U7CiAgICAgICAgbV9jZU1hc2tfID0gZ2V0TWFzayhtX2NvbGxhdG9yXy5nZXRTdHJlbmd0aCgpKTsKICAgICAgICAvLyBpZiBzdGF0dXMgaXMgYSBmYWlsdXJlLCB1Y29sX2dldEF0dHJpYnV0ZSByZXR1cm5zIFVDT0xfREVGQVVMVAogICAgICAgIGluaXRpYWxpemUoKTsKICAgICAgICBtX2NvbEVJdGVyXy5zZXRDb2xsYXRvcihtX2NvbGxhdG9yXyk7CiAgICAgICAgbV9jb2xFSXRlcl8ucmVzZXQoKTsKICAgICAgICBtX3V0aWxDb2xFSXRlcl8uc2V0Q29sbGF0b3IobV9jb2xsYXRvcl8pOwoJfQoKICAgIC8vIHByb3RlY3RlZCBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAKICAgIC8qKgogICAgICogPHA+CiAgICAgKiBDb25jcmV0ZSBtZXRob2QgdG8gcHJvdmlkZSB0aGUgbWVjaGFuaXNtIAogICAgICogZm9yIGZpbmRpbmcgdGhlIG5leHQgPGI+Zm9yd2FyZHM8L2I+IG1hdGNoIGluIHRoZSB0YXJnZXQgdGV4dC4KICAgICAqIFNlZSBzdXBlciBjbGFzcyBkb2N1bWVudGF0aW9uIGZvciBpdHMgdXNlLgogICAgICogPC9wPiAgCiAgICAgKiBAcGFyYW0gc3RhcnQgaW5kZXggaW4gdGhlIHRhcmdldCB0ZXh0IGF0IHdoaWNoIHRoZSBmb3J3YXJkcyBzZWFyY2ggCiAgICAgKiAgICAgICAgc2hvdWxkIGJlZ2luLgogICAgICogQHJldHVybiB0aGUgc3RhcnRpbmcgaW5kZXggb2YgdGhlIG5leHQgZm9yd2FyZHMgbWF0Y2ggaWYgZm91bmQsIERPTkUgCiAgICAgKiAgICAgICAgIG90aGVyd2lzZQogICAgICogQHNlZSAjaGFuZGxlUHJldmlvdXMoaW50KQogICAgICogQHNlZSAjRE9ORQogICAgICogQGRyYWZ0IElDVSAyLjIKICAgICAqLwogICAgcHJvdGVjdGVkIGludCBoYW5kbGVOZXh0KGludCBzdGFydCkKICAgIHsKICAgIAlpZiAobV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyA9PSAwKSB7CiAgICAgICAgICAgIG1hdGNoTGVuZ3RoID0gMDsKICAgICAgICAgICAgaWYgKG1fbWF0Y2hlZEluZGV4XyA9PSBET05FICYmIHN0YXJ0ID09IG1fdGV4dEJlZ2luT2Zmc2V0XykgewogICAgICAgICAgICAgICAgbV9tYXRjaGVkSW5kZXhfID0gc3RhcnQ7CiAgICAgICAgICAgICAgICByZXR1cm4gbV9tYXRjaGVkSW5kZXhfOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgCQl0YXJnZXRUZXh0LnNldEluZGV4KHN0YXJ0KTsKCSAgICAgICAgY2hhciBjaCA9IHRhcmdldFRleHQuY3VycmVudCgpOwoJICAgICAgICAvLyBjaCBjYW4gbmV2ZXIgYmUgZG9uZSwgaXQgaXMgaGFuZGxlZCBieSBuZXh0KCkKCSAgICAgICAgY2hhciBjaDIgPSB0YXJnZXRUZXh0Lm5leHQoKTsKCSAgICAgICAgaWYgKGNoMiA9PSBDaGFyYWN0ZXJJdGVyYXRvci5ET05FKSB7CgkgICAgICAgICAgICBtX21hdGNoZWRJbmRleF8gPSBET05FOwkKCSAgICAgICAgfQoJICAgICAgICBlbHNlIHsKCSAgICAgICAgICAgIG1fbWF0Y2hlZEluZGV4XyA9IHRhcmdldFRleHQuZ2V0SW5kZXgoKTsKCSAgICAgICAgfQoJICAgICAgICBpZiAoVVRGMTYuaXNMZWFkU3Vycm9nYXRlKGNoKSAmJiBVVEYxNi5pc1RyYWlsU3Vycm9nYXRlKGNoMikpIHsKCSAgICAgICAgICAgIHRhcmdldFRleHQubmV4dCgpOwoJICAgICAgICAgICAgbV9tYXRjaGVkSW5kZXhfID0gdGFyZ2V0VGV4dC5nZXRJbmRleCgpOwoJICAgICAgICB9CgkgICAgfQoJICAgIGVsc2UgewoJICAgIAlpZiAobWF0Y2hMZW5ndGggIT0gMCkgewoJCSAgICAJc3RhcnQgKz0gbWF0Y2hMZW5ndGg7CgkJICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAvLyB3ZSBtdXN0IGhhdmUgcmV2ZXJzZWQgZGlyZWN0aW9uIGFmdGVyIHdlIHJlYWNoZWQgdGhlIHN0YXJ0CiAgICAgICAgICAgICAgICAvLyBvZiB0aGUgdGFyZ2V0IHRleHQKICAgICAgICAgICAgICAgIC8vIHNlZSBTZWFyY2hJdGVyYXRvciBuZXh0KCksIGl0IGNoZWNrcyB0aGUgYm91bmRzIGFuZCByZXR1cm5zCiAgICAgICAgICAgICAgICAvLyBpZiBpdCBleGNlZWRzIHRoZSByYW5nZS4gSXQgZG9lcyBub3QgYWxsb3cgc2V0dGluZyBvZgogICAgICAgICAgICAgICAgLy8gbV9tYXRjaGVkSW5kZXgKICAgICAgICAgICAgICAgIG1fbWF0Y2hlZEluZGV4XyA9IERPTkU7CiAgICAgICAgICAgIH0KICAgIAoJICAgICAgICAvLyBzdGF0dXMgY2hlY2tlZCBiZWxvdwoJICAgICAgICBpZiAobV9pc0Nhbm9uaWNhbE1hdGNoXykgewoJICAgICAgICAgICAgLy8gY2FuJ3QgdXNlIGV4YWN0IGhlcmUgc2luY2UgZXh0cmEgYWNjZW50cyBhcmUgYWxsb3dlZC4KCSAgICAgICAgICAgIGhhbmRsZU5leHRDYW5vbmljYWwoc3RhcnQpOwoJICAgICAgICB9CgkgICAgICAgIGVsc2UgewoJICAgICAgICAgICAgaGFuZGxlTmV4dEV4YWN0KHN0YXJ0KTsKCSAgICAgICAgfQoJICAgIH0KICAgICAgICBpZiAobV9tYXRjaGVkSW5kZXhfID09IERPTkUpIHsKICAgICAgICAgICAgdGFyZ2V0VGV4dC5zZXRJbmRleChtX3RleHRMaW1pdE9mZnNldF8pOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgdGFyZ2V0VGV4dC5zZXRJbmRleChtX21hdGNoZWRJbmRleF8pOwogICAgICAgIH0KICAgIAlyZXR1cm4gbV9tYXRjaGVkSW5kZXhfOwogICAgfQogICAgCiAgICAvKioKCSAqIDxwPgogICAgICogQ29uY3JldGUgbWV0aG9kIHRvIHByb3ZpZGUgdGhlIG1lY2hhbmlzbSAKICAgICAqIGZvciBmaW5kaW5nIHRoZSBuZXh0IDxiPmJhY2t3YXJkczwvYj4gbWF0Y2ggaW4gdGhlIHRhcmdldCB0ZXh0LgogICAgICogU2VlIHN1cGVyIGNsYXNzIGRvY3VtZW50YXRpb24gZm9yIGl0cyB1c2UuCiAgICAgKiA8L3A+ICAKICAgICAqIEBwYXJhbSBzdGFydCBpbmRleCBpbiB0aGUgdGFyZ2V0IHRleHQgYXQgd2hpY2ggdGhlIGJhY2t3YXJkcyBzZWFyY2ggCiAgICAgKiAgICAgICAgc2hvdWxkIGJlZ2luLgogICAgICogQHJldHVybiB0aGUgc3RhcnRpbmcgaW5kZXggb2YgdGhlIG5leHQgYmFja3dhcmRzIG1hdGNoIGlmIGZvdW5kLCBET05FIAogICAgICogICAgICAgICBvdGhlcndpc2UKICAgICAqIEBzZWUgI2hhbmRsZU5leHQoaW50KQogICAgICogQHNlZSAjRE9ORQogICAgICogQGRyYWZ0IElDVSAyLjIKCSAqLwogICAgcHJvdGVjdGVkIGludCBoYW5kbGVQcmV2aW91cyhpbnQgc3RhcnQpCiAgICB7CiAgICAJaWYgKG1fcGF0dGVybl8ubV9DRUxlbmd0aF8gPT0gMCkgewogICAgICAgICAgICBtYXRjaExlbmd0aCA9IDA7CgkgICAgICAgIC8vIHN0YXJ0IGNhbiBuZXZlciBiZSBET05FIG9yIDAsIGl0IGlzIGhhbmRsZWQgaW4gcHJldmlvdXMKICAgICAgICAgICAgdGFyZ2V0VGV4dC5zZXRJbmRleChzdGFydCk7CiAgICAgICAgICAgIGNoYXIgY2ggPSB0YXJnZXRUZXh0LnByZXZpb3VzKCk7CiAgICAgICAgICAgIGlmIChjaCA9PSBDaGFyYWN0ZXJJdGVyYXRvci5ET05FKSB7CiAgICAgICAgICAgIAltX21hdGNoZWRJbmRleF8gPSBET05FOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAJbV9tYXRjaGVkSW5kZXhfID0gdGFyZ2V0VGV4dC5nZXRJbmRleCgpOwoJICAgICAgICAgICAgaWYgKFVURjE2LmlzVHJhaWxTdXJyb2dhdGUoY2gpKSB7CgkgICAgICAgICAgICAJaWYgKFVURjE2LmlzTGVhZFN1cnJvZ2F0ZSh0YXJnZXRUZXh0LnByZXZpb3VzKCkpKSB7CgkgICAgICAgICAgICAgICAgICAgIG1fbWF0Y2hlZEluZGV4XyA9IHRhcmdldFRleHQuZ2V0SW5kZXgoKTsKCSAgICAgICAgICAgIAl9CgkgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gICAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGlmIChtYXRjaExlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgICAgICAvLyB3ZSBtdXN0IGhhdmUgcmV2ZXJzZWQgZGlyZWN0aW9uIGFmdGVyIHdlIHJlYWNoZWQgdGhlIGVuZAogICAgICAgICAgICAgICAgLy8gb2YgdGhlIHRhcmdldCB0ZXh0CiAgICAgICAgICAgICAgICAvLyBzZWUgU2VhcmNoSXRlcmF0b3IgbmV4dCgpLCBpdCBjaGVja3MgdGhlIGJvdW5kcyBhbmQgcmV0dXJucwogICAgICAgICAgICAgICAgLy8gaWYgaXQgZXhjZWVkcyB0aGUgcmFuZ2UuIEl0IGRvZXMgbm90IGFsbG93IHNldHRpbmcgb2YKICAgICAgICAgICAgICAgIC8vIG1fbWF0Y2hlZEluZGV4CiAgICAgICAgICAgICAgICBtX21hdGNoZWRJbmRleF8gPSBET05FOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChtX2lzQ2Fub25pY2FsTWF0Y2hfKSB7CiAgICAgICAgICAgICAgICAvLyBjYW4ndCB1c2UgZXhhY3QgaGVyZSBzaW5jZSBleHRyYSBhY2NlbnRzIGFyZSBhbGxvd2VkLgogICAgICAgICAgICAgICAgaGFuZGxlUHJldmlvdXNDYW5vbmljYWwoc3RhcnQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgaGFuZGxlUHJldmlvdXNFeGFjdChzdGFydCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChtX21hdGNoZWRJbmRleF8gPT0gRE9ORSkgewogICAgICAgICAgICB0YXJnZXRUZXh0LnNldEluZGV4KG1fdGV4dEJlZ2luT2Zmc2V0Xyk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICB0YXJnZXRUZXh0LnNldEluZGV4KG1fbWF0Y2hlZEluZGV4Xyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtX21hdGNoZWRJbmRleF87CiAgICB9CgogICAgLy8gcHJpdmF0ZSBzdGF0aWMgaW5uZXIgY2xhc3NlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAKICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFBhdHRlcm4gCiAgICB7CiAgICAJLy8gcHJvdGVjdGVkIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIAkKICAgIAkvKioKICAgIAkgKiBQYXR0ZXJuIHN0cmluZwogICAgCSAqLwogICAgCXByb3RlY3RlZCBTdHJpbmcgdGFyZ2V0VGV4dDsKICAgICAgICAvKioKICAgICAgICAgKiBBcnJheSBjb250YWluaW5nIHRoZSBjb2xsYXRpb24gZWxlbWVudHMgb2YgdGFyZ2V0VGV4dAogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBpbnQgbV9DRV9bXTsKICAgICAgICAvKioKICAgICAgICAgKiBOdW1iZXIgb2YgY29sbGF0aW9uIGVsZW1lbnRzIGluIG1fQ0VfCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIGludCBtX0NFTGVuZ3RoXzsgCiAgICAgICAgLyoqCiAgICAgICAgICogRmxhZyBpbmRpY2F0b3IgaWYgdGFyZ2V0VGV4dCBzdGFydHMgd2l0aCBhbiBhY2NlbnQKICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiBtX2hhc1ByZWZpeEFjY2VudHNfOwogICAgICAgIC8qKgogICAgICAgICAqIEZsYWcgaW5kaWNhdG9yIGlmIHRhcmdldFRleHQgZW5kcyB3aXRoIGFuIGFjY2VudAogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBib29sZWFuIG1faGFzU3VmZml4QWNjZW50c187CiAgICAgICAgLyoqCiAgICAgICAgICogRGVmYXVsdCBudW1iZXIgb2YgY2hhcmFjdGVycyB0byBzaGlmdCBmb3IgQm95ZXIgTW9vcmUKICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgaW50IG1fZGVmYXVsdFNoaWZ0U2l6ZV87CiAgICAgICAgLyoqCiAgICAgICAgICogTnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gc2hpZnQgZm9yIEJveWVyIE1vb3JlLCBkZXBlbmRpbmcgb24gdGhlCiAgICAgICAgICogc291cmNlIHRleHQgdG8gc2VhcmNoCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIGNoYXIgbV9zaGlmdF9bXTsKICAgICAgICAvKioKICAgICAgICAgKiBOdW1iZXIgb2YgY2hhcmFjdGVycyB0byBzaGlmdCBiYWNrd2FyZHMgZm9yIEJveWVyIE1vb3JlLCBkZXBlbmRpbmcgCiAgICAgICAgICogb24gdGhlIHNvdXJjZSB0ZXh0IHRvIHNlYXJjaAogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBjaGFyIG1fYmFja1NoaWZ0X1tdOwogICAgICAgIAogICAgICAgIC8vIHByb3RlY3RlZCBjb25zdHJ1Y3RvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgCiAgICAgICAgLyoqCiAgICAgICAgICogRW1wdHkgY29uc3RydWN0b3IgCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIFBhdHRlcm4oU3RyaW5nIHBhdHRlcm4pIAogICAgICAgIHsKICAgICAgICAJdGFyZ2V0VGV4dCA9IHBhdHRlcm47CiAgICAgICAgCW1fQ0VfID0gbmV3IGludFtJTklUSUFMX0FSUkFZX1NJWkVfXTsJCiAgICAgICAgCW1fQ0VMZW5ndGhfID0gMDsKICAgICAgICAJbV9oYXNQcmVmaXhBY2NlbnRzXyA9IGZhbHNlOwogICAgICAgIAltX2hhc1N1ZmZpeEFjY2VudHNfID0gZmFsc2U7CiAgICAgICAgCW1fZGVmYXVsdFNoaWZ0U2l6ZV8gPSAxOwkJCiAgICAgICAgCW1fc2hpZnRfID0gbmV3IGNoYXJbTUFYX1RBQkxFX1NJWkVfXTsKICAgICAgICAJbV9iYWNrU2hpZnRfID0gbmV3IGNoYXJbTUFYX1RBQkxFX1NJWkVfXTsKICAgICAgICB9CiAgICB9OwoKCiAgICAvLyBwcml2YXRlIGRhdGEgbWVtYmVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIAogICAgLyoqCiAgICAgKiB0YXJnZXQgdGV4dCBiZWdpbiBvZmZzZXQuIEVhY2ggdGFyZ2V0VGV4dCBoYXMgYSB2YWxpZCBjb250aWd1b3VzIHJlZ2lvbiAKICAgICAqIHRvIGl0ZXJhdGUgYW5kIHRoaXMgZGF0YSBtZW1iZXIgaXMgdGhlIG9mZnNldCB0byB0aGUgZmlyc3Qgc3VjaAogICAgICogY2hhcmFjdGVyIGluIHRoZSByZWdpb24uCiAgICAgKi8KICAgIHByaXZhdGUgaW50IG1fdGV4dEJlZ2luT2Zmc2V0XzsKICAgIC8qKgogICAgICogdGFyZ2V0IHRleHQgbGltaXQgb2Zmc2V0LiBFYWNoIHRhcmdldFRleHQgaGFzIGEgdmFsaWQgY29udGlndW91cyByZWdpb24gCiAgICAgKiB0byBpdGVyYXRlIGFuZCB0aGlzIGRhdGEgbWVtYmVyIGlzIHRoZSBvZmZzZXQgdG8gMSBhZnRlciB0aGUgbGFzdCBzdWNoCiAgICAgKiBjaGFyYWN0ZXIgaW4gdGhlIHJlZ2lvbi4KICAgICAqLwogICAgcHJpdmF0ZSBpbnQgbV90ZXh0TGltaXRPZmZzZXRfOwogICAgLyoqCiAgICAgKiBVcG9uIGNvbXBsZXRpb24gb2YgYSBzZWFyY2gsIG1fbWF0Y2hJbmRleF8gd2lsbCBzdG9yZSBzdGFydGluZyBvZmZzZXQgaW4KICAgICAqIG1fdGV4dCBmb3IgdGhlIG1hdGNoLiBUaGUgVmFsdWUgRE9ORSBpcyB0aGUgZGVmYXVsdCB2YWx1ZS4gCiAgICAgKiBJZiB3ZSBhcmUgbm90IGF0IHRoZSBzdGFydCBvZiB0aGUgdGV4dCBvciB0aGUgZW5kIG9mIHRoZSB0ZXh0IGFuZCAKICAgICAqIG1fbWF0Y2hlZEluZGV4XyBpcyBET05FIGl0IG1lYW5zIHRoYXQgd2UgY2FuIGZpbmQgYW55IG1vcmUgbWF0Y2hlcyBpbiAKICAgICAqIHRoYXQgcGFydGljdWxhciBkaXJlY3Rpb24KICAgICAqLwogICAgcHJpdmF0ZSBpbnQgbV9tYXRjaGVkSW5kZXhfOyAKICAgIC8qKgogICAgICogQ3VycmVudCBwYXR0ZXJuIHRvIHNlYXJjaCBmb3IKICAgICAqLwogICAgcHJpdmF0ZSBQYXR0ZXJuIG1fcGF0dGVybl87CiAgICAvKioKICAgICAqIENvbGxhdG9yIHdob3NlIHJ1bGVzIGFyZSB1c2VkIHRvIHBlcmZvcm0gdGhlIHNlYXJjaAogICAgICovCiAgICBwcml2YXRlIFJ1bGVCYXNlZENvbGxhdG9yIG1fY29sbGF0b3JfOwogICAgLyoqIAogICAgICogVGhlIGNvbGxhdGlvbiBlbGVtZW50IGl0ZXJhdG9yIGZvciB0aGUgdGV4dCBzb3VyY2UuCiAgICAgKi8KICAgIHByaXZhdGUgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIG1fY29sRUl0ZXJfOwogICAgLyoqIAogICAgICogVXRpbGl0eSBjb2xsYXRpb24gZWxlbWVudCwgdXNlZCB0aHJvdWdob3V0IHByb2dyYW0gZm9yIHRlbXBvcmFyeSAKICAgICAqIGl0ZXJhdGlvbi4KICAgICAqLwogICAgcHJpdmF0ZSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgbV91dGlsQ29sRUl0ZXJfOwogICAgLyoqCiAgICAgKiBUaGUgbWFzayB1c2VkIG9uIHRoZSBjb2xsYXRpb24gZWxlbWVudHMgdG8gcmV0cmlldmUgdGhlIHZhbGlkIHN0cmVuZ3RoCiAgICAgKiB3ZWlnaHQgCiAgICAgKi8KICAgIHByaXZhdGUgaW50IG1fY2VNYXNrXzsKICAgIC8qKgogICAgICogQnVmZmVyIHN0b3JpbmcgYWNjZW50cyBkdXJpbmcgYSBjYW5vbmljYWwgc2VhcmNoCiAgICAgKi8KICAgIHByaXZhdGUgU3RyaW5nQnVmZmVyIG1fY2Fub25pY2FsUHJlZml4QWNjZW50c187CiAgICAvKioKICAgICAqIEJ1ZmZlciBzdG9yaW5nIGFjY2VudHMgZHVyaW5nIGEgY2Fub25pY2FsIHNlYXJjaAogICAgICovCiAgICBwcml2YXRlIFN0cmluZ0J1ZmZlciBtX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfOwogICAgLyoqCiAgICAgKiBGbGFnIHRvIGluZGljYXRlIGlmIGNhbm9uaWNhbCBzZWFyY2ggaXMgdG8gYmUgZG9uZS4KICAgICAqIEUuZyBsb29raW5nIGZvciAiYVx1MDMwMCIgaW4gImFcdTAzMThcdTAzMDAiIHdpbGwgeWllbGQgdGhlIG1hdGNoIGF0IDAuCiAgICAgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBtX2lzQ2Fub25pY2FsTWF0Y2hfOwogICAgLyoqCiAgICAgKiBTaXplIG9mIHRoZSBzaGlmdCB0YWJsZXMKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9UQUJMRV9TSVpFXyA9IDI1NzsgCiAgICAvKioKICAgICAqIEluaXRpYWwgYXJyYXkgc2l6ZQogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5JVElBTF9BUlJBWV9TSVpFXyA9IDI1NjsKICAgIC8qKgogICAgICogVXRpbGl0eSBtYXNrCiAgICAgKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTRUNPTkRfTEFTVF9CWVRFX1NISUZUXyA9IDg7CgkvKioKICAgICAqIFV0aWxpdHkgbWFzawogICAgICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTEFTVF9CWVRFX01BU0tfID0gMHhmZjsKCS8qKgoJICogVXRpbGl0eSBidWZmZXIgZm9yIHJldHVybiB2YWx1ZXMgYW5kIHRlbXBvcmFyeSBzdG9yYWdlCgkgKi8KCXByaXZhdGUgaW50IG1fdXRpbEJ1ZmZlcl9bXSA9IG5ldyBpbnRbMl07CgoJLy8gcHJpdmF0ZSBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvKioKICAgICAqIEhhc2ggYSBjb2xsYXRpb24gZWxlbWVudCBmcm9tIGl0cyBmdWxsIHNpemUgKDMyIGJpdHMpIGRvd24gaW50byBhCiAgICAgKiB2YWx1ZSB0aGF0IGNhbiBiZSB1c2VkIGFzIGFuIGluZGV4IGludG8gdGhlIHNoaWZ0IHRhYmxlcy4gIFJpZ2h0CiAgICAgKiBub3cgd2UgZG8gYSBtb2R1bHVzIGJ5IHRoZSBzaXplIG9mIHRoZSBoYXNoIHRhYmxlLgogICAgICogQHBhcmFtIGNlIGNvbGxhdGlvbiBlbGVtZW50CgkgKiBAcmV0dXJuIGNvbGxhcHNlZCB2ZXJzaW9uIG9mIHRoZSBjb2xsYXRpb24gZWxlbWVudAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgaGFzaChpbnQgY2UpIAogICAgewogICAgICAgIC8vIHRoZSBvbGQgdmFsdWUgVUNPTF9QUklNQVJZT1JERVIoY2UpICUgTUFYX1RBQkxFX1NJWkVfIGRvZXMgbm90IHdvcmsKICAgIAkvLyB3ZWxsIHdpdGggdGhlIG5ldyBjb2xsYXRpb24gd2hlcmUgbW9zdCBvZiB0aGUgbGF0aW4gMSBjaGFyYWN0ZXJzCiAgICAJLy8gYXJlIG9mIHRoZSB2YWx1ZSB4eDAwMHh4eC4gdGhlaXIgaGFzaGVzIHdpbGwgbW9zdCBvZiB0aGUgdGltZSBiZSAwCiAgICAJLy8gdG8gYmUgZGlzY3Vzc2VkIG9uIHRoZSBoYXNoIGFsZ28uCiAgICAJcmV0dXJuIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5wcmltYXJ5T3JkZXIoY2UpICUgTUFYX1RBQkxFX1NJWkVfOwogICAgfQogICAgCiAgICAvKioKCSAqIEdldHMgdGhlIGZjZCB2YWx1ZSBmb3IgYSBjaGFyYWN0ZXIgYXQgdGhlIGFyZ3VtZW50IGluZGV4LgoJICogVGhpcyBtZXRob2QgdGFrZXMgaW50byBhY2NvdW50cyBvZiB0aGUgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzLgoJICogTm90ZSB0aGlzIG1ldGhvZCBjaGFuZ2VzIHRoZSBvZmZzZXQgaW4gdGhlIGNoYXJhY3RlciBpdGVyYXRvci4KCSAqIEBwYXJhbSBzdHIgVVRGMTYgc3RyaW5nIHdoZXJlIGNoYXJhY3RlciBmb3IgZmNkIHJldHJpZXZhbCByZXNpZGVzCgkgKiBAcGFyYW0gb2Zmc2V0IHBvc2l0aW9uIG9mIHRoZSBjaGFyYWN0ZXIgd2hvc2UgZmNkIGlzIHRvIGJlIHJldHJpZXZlZAoJICogQHJldHVybiBmY2QgdmFsdWUKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhciBnZXRGQ0QoQ2hhcmFjdGVySXRlcmF0b3Igc3RyLCBpbnQgb2Zmc2V0KQoJewoJICAgIHN0ci5zZXRJbmRleChvZmZzZXQpOwoJICAgIGNoYXIgY2ggPSBzdHIuY3VycmVudCgpOwoJICAgIGNoYXIgcmVzdWx0ID0gTm9ybWFsaXplckltcGwuZ2V0RkNEMTYoY2gpOwoJICAgIAoJICAgIGlmICgocmVzdWx0ICE9IDApICYmIChzdHIuZ2V0RW5kSW5kZXgoKSAhPSBvZmZzZXQgKyAxKSAmJiAKCSAgICAJVVRGMTYuaXNMZWFkU3Vycm9nYXRlKGNoKSkgewoJICAgICAgICBjaCA9IHN0ci5uZXh0KCk7CgkgICAgICAgIGlmIChVVEYxNi5pc1RyYWlsU3Vycm9nYXRlKGNoKSkgewoJICAgICAgICAgICAgcmVzdWx0ID0gTm9ybWFsaXplckltcGwuZ2V0RkNEMTZGcm9tU3Vycm9nYXRlUGFpcihyZXN1bHQsIGNoKTsKCSAgICAgICAgfSBlbHNlIHsKCSAgICAgICAgICAgIHJlc3VsdCA9IDA7CgkgICAgICAgIH0KCSAgICB9CgkgICAgcmV0dXJuIHJlc3VsdDsKCX0KCQoJLyoqCgkgKiBHZXRzIHRoZSBmY2QgdmFsdWUgZm9yIGEgY2hhcmFjdGVyIGF0IHRoZSBhcmd1bWVudCBpbmRleC4KCSAqIFRoaXMgbWV0aG9kIHRha2VzIGludG8gYWNjb3VudHMgb2YgdGhlIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVycy4KCSAqIEBwYXJhbSBzdHIgVVRGMTYgc3RyaW5nIHdoZXJlIGNoYXJhY3RlciBmb3IgZmNkIHJldHJpZXZhbCByZXNpZGVzCgkgKiBAcGFyYW0gb2Zmc2V0IHBvc2l0aW9uIG9mIHRoZSBjaGFyYWN0ZXIgd2hvc2UgZmNkIGlzIHRvIGJlIHJldHJpZXZlZAoJICogQHJldHVybiBmY2QgdmFsdWUKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhciBnZXRGQ0QoU3RyaW5nIHN0ciwgaW50IG9mZnNldCkKCXsKCSAgICBjaGFyIGNoID0gc3RyLmNoYXJBdChvZmZzZXQpOwoJICAgIGNoYXIgcmVzdWx0ID0gTm9ybWFsaXplckltcGwuZ2V0RkNEMTYoY2gpOwoJICAgIAoJICAgIGlmICgocmVzdWx0ICE9IDApICYmIChzdHIubGVuZ3RoKCkgIT0gb2Zmc2V0ICsgMSkgJiYgCgkgICAgCVVURjE2LmlzTGVhZFN1cnJvZ2F0ZShjaCkpIHsKCSAgICAgICAgY2ggPSBzdHIuY2hhckF0KG9mZnNldCArIDEpOwoJICAgICAgICBpZiAoVVRGMTYuaXNUcmFpbFN1cnJvZ2F0ZShjaCkpIHsKCSAgICAgICAgICAgIHJlc3VsdCA9IE5vcm1hbGl6ZXJJbXBsLmdldEZDRDE2RnJvbVN1cnJvZ2F0ZVBhaXIocmVzdWx0LCBjaCk7CgkgICAgICAgIH0gZWxzZSB7CgkgICAgICAgICAgICByZXN1bHQgPSAwOwoJICAgICAgICB9CgkgICAgfQoJICAgIHJldHVybiByZXN1bHQ7Cgl9CgkKCS8qKgoJKiBHZXR0aW5nIHRoZSBtb2RpZmllZCBjb2xsYXRpb24gZWxlbWVudHMgdGFraW5nIGludG8gYWNjb3VudCB0aGUgY29sbGF0aW9uIAoJKiBhdHRyaWJ1dGVzCgkqIEBwYXJhbSBjZSAKCSogQHJldHVybiB0aGUgbW9kaWZpZWQgY29sbGF0aW9uIGVsZW1lbnQKCSovCglwcml2YXRlIGZpbmFsIGludCBnZXRDRShpbnQgY2UpCgl7CgkgICAgLy8gbm90ZSBmb3IgdGVydGlhcnkgd2UgY2FuJ3QgdXNlIHRoZSBjb2xsYXRvci0+dGVydGlhcnlNYXNrLCB0aGF0CgkgICAgLy8gaXMgYSBwcmVwcm9jZXNzZWQgbWFzayB0aGF0IHRha2VzIGludG8gYWNjb3VudCBjYXNlIG9wdGlvbnMuIHNpbmNlCgkgICAgLy8gd2UgYXJlIG9ubHkgY29uY2VybmVkIHdpdGggZXhhY3QgbWF0Y2hlcywgd2UgZG9uJ3QgbmVlZCB0aGF0LgoJICAgIGNlICY9IG1fY2VNYXNrXzsKCSAgICAKCSAgICBpZiAobV9jb2xsYXRvcl8uaXNBbHRlcm5hdGVIYW5kbGluZ1NoaWZ0ZWQoKSkgewoJICAgICAgICAvLyBhbHRlcm5hdGUgaGFuZGxpbmcgaGVyZSwgc2luY2Ugb25seSB0aGUgMTYgbW9zdCBzaWduaWZpY2FudCAKCSAgICAgICAgLy8gZGlnaXRzIGlzIG9ubHkgdXNlZCwgd2UgY2FuIHNhZmVseSBkbyBhIGNvbXBhcmUgd2l0aG91dCBtYXNraW5nCgkgICAgICAgIC8vIGlmIHRoZSBjZSBpcyBhIHZhcmlhYmxlLCB3ZSBtYXNrIGFuZCBnZXQgb25seSB0aGUgcHJpbWFyeSB2YWx1ZXMKCSAgICAgICAgLy8gbm8gc2hpZnRpbmcgdG8gcXVhcnRlbmFyeSBpcyByZXF1aXJlZCBzaW5jZSBhbGwgcHJpbWFyeSB2YWx1ZXMKCSAgICAgICAgLy8gbGVzcyB0aGFuIHZhcmlhYmxldG9wIHdpbGwgbmVlZCB0byBiZSBtYXNrZWQgb2ZmIGFueXdheS4KCSAgICAgICAgaWYgKChtX2NvbGxhdG9yXy5tX3ZhcmlhYmxlVG9wVmFsdWVfICA8PCAxNikgPiBjZSkgewoJICAgICAgICAgICAgaWYgKG1fY29sbGF0b3JfLmdldFN0cmVuZ3RoKCkgPT0gQ29sbGF0b3IuUVVBVEVSTkFSWSkgewoJICAgICAgICAgICAgICAgIGNlID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLnByaW1hcnlPcmRlcihjZSk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBlbHNlIHsgCgkgICAgICAgICAgICAgICAgY2UgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgfQoJCgkgICAgcmV0dXJuIGNlOwoJfQoJCgkvKioKCSAqIEFwcGVuZHMgYSBpbnQgdG8gYSBpbnQgYXJyYXksIGluY3JlYXNpbmcgdGhlIHNpemUgb2YgdGhlIGFycmF5IHdoZW4gCgkgKiB3ZSBhcmUgb3V0IG9mIHNwYWNlLgoJICogQHBhcmFtIG9mZnNldCBpbiBhcnJheSB0byBhcHBlbmQgdG8KCSAqIEBwYXJhbSB2YWx1ZSB0byBhcHBlbmQKCSAqIEBwYXJhbSBhcnJheSB0byBhcHBlbmQgdG8KCSAqIEByZXR1cm4gdGhlIGFycmF5IGFwcGVuZGVkIHRvLCB0aGlzIGNvdWxkIGJlIGEgbmV3IGFuZCBiaWdnZXIgYXJyYXkKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50W10gYXBwZW5kKGludCBvZmZzZXQsIGludCB2YWx1ZSwgaW50IGFycmF5W10pCgl7CgkJaWYgKG9mZnNldCA+PSBhcnJheS5sZW5ndGgpIHsKCQkJaW50IHRlbXBbXSA9IG5ldyBpbnRbb2Zmc2V0ICsgSU5JVElBTF9BUlJBWV9TSVpFX107CgkJCVN5c3RlbS5hcnJheWNvcHkoYXJyYXksIDAsIHRlbXAsIDAsIGFycmF5Lmxlbmd0aCk7CgkJCWFycmF5ID0gdGVtcDsKCQl9CgkJYXJyYXlbb2Zmc2V0XSA9IHZhbHVlOwoJCXJldHVybiBhcnJheTsKCX0KCQoJLyoqCgkgKiBJbml0aWFsaXppbmcgdGhlIGNlIHRhYmxlIGZvciBhIHBhdHRlcm4uIFN0b3JlcyBub24taWdub3JhYmxlIGNvbGxhdGlvbiAKCSAqIGtleXMuIFRhYmxlIHNpemUgd2lsbCBiZSBlc3RpbWF0ZWQgYnkgdGhlIHNpemUgb2YgdGhlIHBhdHRlcm4gdGV4dC4gCgkgKiBUYWJsZSBleHBhbnNpb24gd2lsbCBiZSBwZXJmb3JtIGFzIHdlIGdvIGFsb25nLiBBZGRpbmcgMSB0byBlbnN1cmUgdGhhdCAKCSAqIHRoZSB0YWJsZSBzaXplIGRlZmluaXRlbHkgaW5jcmVhc2VzLgoJICogSW50ZXJuYWwgbWV0aG9kLCBzdGF0dXMgYXNzdW1lZCB0byBiZSBhIHN1Y2Nlc3MuCgkgKiBAcmV0dXJuIHRvdGFsIG51bWJlciBvZiBleHBhbnNpb25zIAoJICovCglwcml2YXRlIGZpbmFsIGludCBpbml0aWFsaXplUGF0dGVybkNFVGFibGUoKQoJewoJICAgIG1fdXRpbENvbEVJdGVyXy5zZXRUZXh0KG1fcGF0dGVybl8udGFyZ2V0VGV4dCk7CgkgICAgCgkgICAgaW50IG9mZnNldCA9IDA7CgkgICAgaW50IHJlc3VsdCA9IDA7CgkgICAgaW50IGNlID0gbV91dGlsQ29sRUl0ZXJfLm5leHQoKTsKCQoJICAgIHdoaWxlIChjZSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CgkgICAgICAgIGludCBuZXdjZSA9IGdldENFKGNlKTsKCSAgICAgICAgaWYgKG5ld2NlICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgIG1fcGF0dGVybl8ubV9DRV8gPSBhcHBlbmQob2Zmc2V0LCBuZXdjZSwgbV9wYXR0ZXJuXy5tX0NFXyk7CgkgICAgICAgICAgICBvZmZzZXQgKys7CSAgICAgICAgCgkgICAgICAgIH0KCSAgICAgICAgcmVzdWx0ICs9IG1fdXRpbENvbEVJdGVyXy5nZXRNYXhFeHBhbnNpb24oY2UpIC0gMTsKCSAgICAgICAgY2UgPSBtX3V0aWxDb2xFSXRlcl8ubmV4dCgpOwoJICAgIH0KCQoJICAgIG1fcGF0dGVybl8ubV9DRV8gPSBhcHBlbmQob2Zmc2V0LCAwLCBtX3BhdHRlcm5fLm1fQ0VfKTsKCSAgICBtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfID0gb2Zmc2V0OwoJCgkgICAgcmV0dXJuIHJlc3VsdDsKCX0KCQoJLyoqCgkgKiBJbml0aWFsaXplcyB0aGUgcGF0dGVybiBzdHJ1Y3QuCgkgKiBJbnRlcm5hbCBtZXRob2QsIHN0YXR1cyBhc3N1bWVkIHRvIGJlIHN1Y2Nlc3MuCgkgKiBAcmV0dXJuIGV4cGFuc2lvbnNpemUgdGhlIHRvdGFsIGV4cGFuc2lvbiBzaXplIG9mIHRoZSBwYXR0ZXJuCgkgKi8gCglwcml2YXRlIGZpbmFsIGludCBpbml0aWFsaXplUGF0dGVybigpCgl7CgkgICAgbV9wYXR0ZXJuXy5tX2hhc1ByZWZpeEFjY2VudHNfID0gKGdldEZDRChtX3BhdHRlcm5fLnRhcmdldFRleHQsIDApIAoJICAgIAkJCQkJCQkJCSA+PiBTRUNPTkRfTEFTVF9CWVRFX1NISUZUXykgIT0gMDsKCSAgICBtX3BhdHRlcm5fLm1faGFzU3VmZml4QWNjZW50c18gPSAoZ2V0RkNEKG1fcGF0dGVybl8udGFyZ2V0VGV4dCwgCgkgICAgCQkJCQkJCQkJCSBtX3BhdHRlcm5fLnRhcmdldFRleHQubGVuZ3RoKCkgCgkgICAgCQkJCQkJCQkJCSAtIDEpIAoJICAgIAkJCQkJCQkJCSYgTEFTVF9CWVRFX01BU0tfKSAhPSAwOwoJICAgIC8vIHNpbmNlIGludGlhbGl6ZVBhdHRlcm4gaXMgYW4gaW50ZXJuYWwgbWV0aG9kIHN0YXR1cyBpcyBhIHN1Y2Nlc3MuCgkgICAgcmV0dXJuIGluaXRpYWxpemVQYXR0ZXJuQ0VUYWJsZSgpOyAgIAoJfQoJCgkvKioKCSAqIEluaXRpYWxpemluZyBzaGlmdCB0YWJsZXMsIHdpdGggdGhlIGRlZmF1bHQgdmFsdWVzLgoJICogSWYgYSBjb3JyZXNwb25kaW5nIGRlZmF1bHQgdmFsdWUgaXMgMCwgdGhlIHNoaWZ0IHRhYmxlIGlzIG5vdCBzZXQuCgkgKiBAcGFyYW0gc2hpZnQgdGFibGUgZm9yIGZvcndhcmRzIHNoaWZ0IAoJICogQHBhcmFtIGJhY2tzaGlmdCB0YWJsZSBmb3IgYmFja3dhcmRzIHNoaWZ0CgkgKiBAcGFyYW0gY2V0YWJsZSB0YWJsZSBjb250YWluaW5nIHBhdHRlcm4gY2UKCSAqIEBwYXJhbSBjZXNpemUgc2l6ZSBvZiB0aGUgcGF0dGVybiBjZXMKCSAqIEBwYXJhbSBleHBhbnNpb25zaXplIHRvdGFsIHNpemUgb2YgdGhlIGV4cGFuc2lvbnMKCSAqIEBwYXJhbSBkZWZhdWx0Zm9yd2FyZCB0aGUgZGVmYXVsdCBmb3J3YXJkIHZhbHVlCgkgKiBAcGFyYW0gZGVmYXVsdGJhY2t3YXJkIHRoZSBkZWZhdWx0IGJhY2t3YXJkIHZhbHVlCgkgKi8KCSBwcml2YXRlIGZpbmFsIHZvaWQgc2V0U2hpZnRUYWJsZShjaGFyIHNoaWZ0W10sIAoJIAkJCQkJCQkJCQkJICAgY2hhciBiYWNrc2hpZnRbXSwgCgkJCQkJICAgICAgICAgICAgICAgICAgICAgICAgIAkgICBpbnQgY2V0YWJsZVtdLCBpbnQgY2VzaXplLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAJCQkJCSAJICAgaW50IGV4cGFuc2lvbnNpemUsCgkJCQkJICAgICAgICAgICAgICAgICAgICAgICAgIAkgICBjaGFyIGRlZmF1bHRmb3J3YXJkLAogICAgICAgICAgICAgICAgICAgICAgICAgIAkJCQkJIAkgICBjaGFyIGRlZmF1bHRiYWNrd2FyZCkKCXsKCSAgICAvLyBlc3RpbWF0ZSB0aGUgdmFsdWUgdG8gc2hpZnQuIHRvIGRvIHRoYXQgd2UgZXN0aW1hdGUgdGhlIHNtYWxsZXN0IAoJICAgIC8vIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIGdpdmUgdGhlIHJlbGV2YW50IGNlcywgaWUgYXBwcm94aW1hdGVseQoJICAgIC8vIHRoZSBudW1iZXIgb2YgY2VzIG1pbnVzIHRoZWlyIGV4cGFuc2lvbiwgc2luY2UgZXhwYW5zaW9ucyBjYW4gY29tZSAKCSAgICAvLyBmcm9tIGEgY2hhcmFjdGVyLgoJICAgIGZvciAoaW50IGNvdW50ID0gMDsgY291bnQgPCBNQVhfVEFCTEVfU0laRV87IGNvdW50ICsrKSB7CgkgICAgICAgIHNoaWZ0W2NvdW50XSA9IGRlZmF1bHRmb3J3YXJkOwoJICAgIH0KCSAgICBjZXNpemUgLS07IC8vIGRvd24gdG8gdGhlIGxhc3QgaW5kZXgKCSAgICBmb3IgKGludCBjb3VudCA9IDA7IGNvdW50IDwgY2VzaXplOyBjb3VudCArKykgewoJICAgICAgICAvLyBudW1iZXIgb2YgY2VzIGZyb20gcmlnaHQgb2YgYXJyYXkgdG8gdGhlIGNvdW50CgkgICAgICAgIGludCB0ZW1wID0gZGVmYXVsdGZvcndhcmQgLSBjb3VudCAtIDE7CgkgICAgICAgIHNoaWZ0W2hhc2goY2V0YWJsZVtjb3VudF0pXSA9IHRlbXAgPiAxID8gKChjaGFyKXRlbXApIDogMTsKCSAgICB9CgkgICAgc2hpZnRbaGFzaChjZXRhYmxlW2Nlc2l6ZV0pXSA9IDE7CgkgICAgLy8gZm9yIGlnbm9yYWJsZXMgd2UganVzdCBzaGlmdCBieSBvbmUuIHNlZSB0ZXN0IGV4YW1wbGVzLgoJICAgIHNoaWZ0W2hhc2goMCldID0gMTsKCSAgICAKCSAgICBmb3IgKGludCBjb3VudCA9IDA7IGNvdW50IDwgTUFYX1RBQkxFX1NJWkVfOyBjb3VudCArKykgewoJICAgICAgICBiYWNrc2hpZnRbY291bnRdID0gZGVmYXVsdGJhY2t3YXJkOwoJICAgIH0KCSAgICBmb3IgKGludCBjb3VudCA9IGNlc2l6ZTsgY291bnQgPiAwOyBjb3VudCAtLSkgewoJICAgICAgICAvLyB0aGUgb3JpZ2luYWwgdmFsdWUgY291bnQgZG9lcyBub3Qgc2VlbSB0byB3b3JrCgkgICAgICAgIGJhY2tzaGlmdFtoYXNoKGNldGFibGVbY291bnRdKV0gPSAoY2hhcikoY291bnQgPiBleHBhbnNpb25zaXplID8gCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAJCWNvdW50IC0gZXhwYW5zaW9uc2l6ZSA6IDEpOwoJICAgIH0KCSAgICBiYWNrc2hpZnRbaGFzaChjZXRhYmxlWzBdKV0gPSAxOwoJICAgIGJhY2tzaGlmdFtoYXNoKDApXSA9IDE7Cgl9CgkKCS8qKgoJICogPHA+QnVpbGRpbmcgb2YgdGhlIHBhdHRlcm4gY29sbGF0aW9uIGVsZW1lbnQgbGlzdCBhbmQgdGhlIEJveWVyIE1vb3JlIAoJICogU3RyaW5nU2VhcmNoIHRhYmxlLjwvcD4KCSAqIDxwPlRoZSBjYW5vbmljYWwgbWF0Y2ggd2lsbCBvbmx5IGJlIHBlcmZvcm1lZCBhZnRlciB0aGUgZGVmYXVsdCBtYXRjaCAKCSAqIGZhaWxzLjwvcD4KCSAqIDxwPkZvciBib3RoIGNhc2VzIHdlIG5lZWQgdG8gcmVtZW1iZXIgdGhlIHNpemUgb2YgdGhlIGNvbXBvc2VkIGFuZCAKCSAqIGRlY29tcG9zZWQgdmVyc2lvbnMgb2YgdGhlIHN0cmluZy4gU2luY2UgdGhlIEJveWVyLU1vb3JlIHNoaWZ0IAoJICogY2FsY3VsYXRpb25zIHNoaWZ0cyBieSBhIG51bWJlciBvZiBjaGFyYWN0ZXJzIGluIHRoZSB0ZXh0IGFuZCB0cmllcyB0byAKCSAqIG1hdGNoIHRoZSBwYXR0ZXJuIGZyb20gdGhhdCBvZmZzZXQsIHRoZSBzaGlmdCB2YWx1ZSBjYW4gbm90IGJlIHRvbyBsYXJnZSAKCSAqIGluIGNhc2Ugd2UgbWlzcyBzb21lIGNoYXJhY3RlcnMuIFRvIGNob29zZSBhIHJpZ2h0IHNoaWZ0IHNpemUsIHdlIAoJICogZXN0aW1hdGUgdGhlIE5GQyBmb3JtIG9mIHRoZSBhbmQgdXNlIGl0cyBzaXplIGFzIGEgc2hpZnQgZ3VpZGUuIFRoZSBORkMgCgkgKiBmb3JtIHNob3VsZCBiZSB0aGUgc21hbGwgcG9zc2libGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhdHRlcm4uIEFueXdheXMsIAoJICogd2UnbGwgZXJyIG9uIHRoZSBzbWFsbGVyIHNoaWZ0IHNpemUuIEhlbmNlIHRoZSBjYWxjdWxhdGlvbiBmb3IgCgkgKiBtaW5sZW5ndGguIENhbm9uaWNhbCBtYXRjaCB3aWxsIGJlIHBlcmZvcm1lZCBzbGlnaHRseSBkaWZmZXJlbnRseS4gV2UnbGwgCgkgKiBzcGxpdCB0aGUgcGF0dGVybiBpbnRvIDMgcGFydHMsIHRoZSBwcmVmaXggYWNjZW50cyAoUEEpLCB0aGUgbWlkZGxlIAoJICogc3RyaW5nIGJvdW5kZWQgYnkgdGhlIGZpcnN0IGFuZCBsYXN0IGJhc2UgY2hhcmFjdGVyIChNUyksIHRoZSBlbmRpbmcgCgkgKiBhY2NlbnRzIChFQSkuIE1hdGNoZXMgd2lsbCBiZSBkb25lIG9uIE1TIGZpcnN0LCBhbmQgb25seSB3aGVuIHdlIG1hdGNoIAoJICogTVMgdGhlbiBzb21lIHByb2Nlc3Npbmcgd2lsbCBiZSByZXF1aXJlZCBmb3IgdGhlIHByZWZpeCBhbmQgZW5kIGFjY2VudHMgCgkgKiBpbiBvcmRlciB0byBkZXRlcm1pbmUgaWYgdGhleSBtYXRjaCBQQSBhbmQgRUEuIEhlbmNlIHRoZSBkZWZhdWx0IHNoaWZ0IAoJICogdmFsdWVzIGZvciB0aGUgY2Fub25pY2FsIG1hdGNoIHdpbGwgdGFrZSB0aGUgc2l6ZSBvZiBlaXRoZXIgZW5kJ3MgYWNjZW50IAoJICogaW50byBjb25zaWRlcmF0aW9uLiBGb3J3YXJkcyBzZWFyY2ggd2lsbCB0YWtlIHRoZSBlbmQgYWNjZW50cyBpbnRvIAoJICogY29uc2lkZXJhdGlvbiBmb3IgdGhlIGRlZmF1bHQgc2hpZnQgdmFsdWVzIGFuZCB0aGUgYmFja3dhcmRzIHNlYXJjaCB3aWxsIAoJICogdGFrZSB0aGUgcHJlZml4IGFjY2VudHMgaW50byBjb25zaWRlcmF0aW9uLjwvcD4KCSAqIDxwPklmIHBhdHRlcm4gaGFzIG5vIG5vbi1pZ25vcmFibGUgY2UsIHdlIHJldHVybiBhIGlsbGVnYWwgYXJndW1lbnQgCgkgKiBlcnJvci48L3A+CgkgKi8gCglwcml2YXRlIGZpbmFsIHZvaWQgaW5pdGlhbGl6ZSgpCgl7CgkgICAgaW50IGV4cGFuZGxlbmd0aCAgPSBpbml0aWFsaXplUGF0dGVybigpOyAgIAoJICAgIGlmIChtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfID4gMCkgewoJICAgICAgICBjaGFyIG1pbmxlbmd0aCA9IChjaGFyKShtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfID4gZXhwYW5kbGVuZ3RoIAoJICAgICAgICAJCQkJCT8gbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyAtIGV4cGFuZGxlbmd0aCA6IDEpOwoJICAgICAgICBtX3BhdHRlcm5fLm1fZGVmYXVsdFNoaWZ0U2l6ZV8gPSBtaW5sZW5ndGg7CiAgICAgICAgICAgIHNldFNoaWZ0VGFibGUobV9wYXR0ZXJuXy5tX3NoaWZ0XywgbV9wYXR0ZXJuXy5tX2JhY2tTaGlmdF8sIAoJICAgICAgICAJCQkgIG1fcGF0dGVybl8ubV9DRV8sIG1fcGF0dGVybl8ubV9DRUxlbmd0aF8sIAoJICAgICAgICAJCQkgIGV4cGFuZGxlbmd0aCwgbWlubGVuZ3RoLCBtaW5sZW5ndGgpOwoJICAgIH0KCSAgICBlbHNlIHsKCSAgICAJbV9wYXR0ZXJuXy5tX2RlZmF1bHRTaGlmdFNpemVfID0gMDsKCSAgICB9Cgl9CgkKCS8qKgoJICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIHNlYXJjaCB0ZXh0IGJvdW5kZWQgYnkgdGhlIG9mZnNldCBzdGFydCBhbmQgZW5kIGlzIAoJICogb25lIG9yIG1vcmUgd2hvbGUgdW5pdHMgb2YgdGV4dCBhcyBkZXRlcm1pbmVkIGJ5IHRoZSBicmVha2l0ZXJhdG9yIGluIAoJICogU3RyaW5nU2VhcmNoLgoJICogQHBhcmFtIHN0YXJ0IHRhcmdldCB0ZXh0IHN0YXJ0IG9mZnNldAoJICogQHBhcmFtIGVuZCB0YXJnZXQgdGV4dCBlbmQgb2Zmc2V0CgkgKi8KCXByaXZhdGUgZmluYWwgYm9vbGVhbiBpc0JyZWFrVW5pdChpbnQgc3RhcnQsIGludCBlbmQpIAoJewoJICAgIGlmIChicmVha0l0ZXJhdG9yICE9IG51bGwpIHsKCSAgICAgICAgaW50IHN0YXJ0aW5kZXggPSBicmVha0l0ZXJhdG9yLmZpcnN0KCk7CgkgICAgICAgIGludCBlbmRpbmRleCAgID0gYnJlYWtJdGVyYXRvci5sYXN0KCk7CgkgICAgICAgIAoJICAgICAgICAvLyBvdXQtb2YtcmFuZ2UgaW5kZXhlcyBhcmUgbmV2ZXIgYm91bmRhcnkgcG9zaXRpb25zCgkgICAgICAgIGlmIChzdGFydCA8IHN0YXJ0aW5kZXggfHwgc3RhcnQgPiBlbmRpbmRleCB8fCBlbmQgPCBzdGFydGluZGV4IAoJICAgICAgICAJfHwgZW5kID4gZW5kaW5kZXgpIHsKCSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICAgICAgfQoJICAgICAgICAvLyBvdGhlcndpc2UsIHdlIGNhbiB1c2UgZm9sbG93aW5nKCkgb24gdGhlIHBvc2l0aW9uIGJlZm9yZSB0aGUgCgkgICAgICAgIC8vIHNwZWNpZmllZCBvbmUgYW5kIHJldHVybiB0cnVlIG9mIHRoZSBwb3NpdGlvbiB3ZSBnZXQgYmFjayBpcyB0aGUgCgkgICAgICAgIC8vIG9uZSB0aGUgdXNlciBzcGVjaWZpZWQKCSAgICAgICAgYm9vbGVhbiByZXN1bHQgPSAoc3RhcnQgPT0gc3RhcnRpbmRleCAKCSAgICAgICAgCQkJCSAgfHwgYnJlYWtJdGVyYXRvci5mb2xsb3dpbmcoc3RhcnQgLSAxKSA9PSBzdGFydCkgCgkgICAgICAgIAkJCQkgJiYgKGVuZCA9PSBlbmRpbmRleCAKCSAgICAgICAgCQkJCSAJIHx8IGJyZWFrSXRlcmF0b3IuZm9sbG93aW5nKGVuZCAtIDEpID09IGVuZCk7CgkgICAgICAgIGlmIChyZXN1bHQpIHsKCSAgICAgICAgICAgIC8vIGl0ZXJhdGVzIHRoZSBpbmRpdmlkdWFsIGNlcwoJICAgICAgICAgICAgbV91dGlsQ29sRUl0ZXJfLnNldFRleHQodGFyZ2V0VGV4dCwgc3RhcnQpOwoJICAgICAgICAgICAgZm9yIChpbnQgY291bnQgPSAwOyBjb3VudCA8IG1fcGF0dGVybl8ubV9DRUxlbmd0aF87CgkgICAgICAgICAgICAgICAgIGNvdW50ICsrKSB7CiAgICAgICAgICAgICAgICAgICAgaW50IGNlID0gZ2V0Q0UobV91dGlsQ29sRUl0ZXJfLm5leHQoKSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY291bnQgLS07CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICBpZiAoY2UgIT0gbV9wYXR0ZXJuXy5tX0NFX1tjb3VudF0pIHsKCSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGludCBuZXh0Y2UgPSBtX3V0aWxDb2xFSXRlcl8ubmV4dCgpOwogICAgICAgICAgICAgICAgd2hpbGUgKG1fdXRpbENvbEVJdGVyXy5nZXRPZmZzZXQoKSA9PSBlbmQgCiAgICAgICAgICAgICAgICAgICAgICAgJiYgZ2V0Q0UobmV4dGNlKSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CiAgICAgICAgICAgICAgICAgICAgbmV4dGNlID0gbV91dGlsQ29sRUl0ZXJfLm5leHQoKTsgICAgICAgCiAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAobmV4dGNlICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIgCgkgICAgICAgICAgICAJJiYgbV91dGlsQ29sRUl0ZXJfLmdldE9mZnNldCgpID09IGVuZCkgewoJICAgICAgICAgICAgICAgIC8vIGV4dHJhIGNvbGxhdGlvbiBlbGVtZW50cyBhdCB0aGUgZW5kIG9mIHRoZSBtYXRjaAoJICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgICAgICByZXR1cm4gcmVzdWx0OwoJICAgIH0KCSAgICByZXR1cm4gdHJ1ZTsKCX0KCQoJLyoqCgkgKiBHZXR0aW5nIHRoZSBuZXh0IGJhc2UgY2hhcmFjdGVyIG9mZnNldCBpZiBjdXJyZW50IG9mZnNldCBpcyBhbiBhY2NlbnQsIAoJICogb3IgdGhlIGN1cnJlbnQgb2Zmc2V0IGlmIHRoZSBjdXJyZW50IGNoYXJhY3RlciBjb250YWlucyBhIGJhc2UgY2hhcmFjdGVyLiAKCSAqIGFjY2VudHMgdGhlIGZvbGxvd2luZyBiYXNlIGNoYXJhY3RlciB3aWxsIGJlIHJldHVybmVkCgkgKiBAcGFyYW0gdGV4dCBzdHJpbmcKCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IGN1cnJlbnQgb2Zmc2V0CgkgKiBAcGFyYW0gdGV4dGxlbmd0aCBsZW5ndGggb2YgdGV4dCBzdHJpbmcKCSAqIEByZXR1cm4gdGhlIG5leHQgYmFzZSBjaGFyYWN0ZXIgb3IgdGhlIGN1cnJlbnQgb2Zmc2V0CgkgKiAgICAgICAgIGlmIHRoZSBjdXJyZW50IGNoYXJhY3RlciBpcyBjb250YWlucyBhIGJhc2UgY2hhcmFjdGVyLgoJICovCglwcml2YXRlIGZpbmFsIGludCBnZXROZXh0QmFzZU9mZnNldChDaGFyYWN0ZXJJdGVyYXRvciB0ZXh0LCAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAJCSBpbnQgdGV4dG9mZnNldCkKCXsKCSAgICBpZiAodGV4dG9mZnNldCA8IHRleHQuZ2V0RW5kSW5kZXgoKSkgewoJICAgICAgICB3aGlsZSAodGV4dC5nZXRJbmRleCgpIDwgdGV4dC5nZXRFbmRJbmRleCgpKSB7IAoJICAgICAgICAgICAgaW50IHJlc3VsdCA9IHRleHRvZmZzZXQ7CgkgICAgICAgICAgICBpZiAoKGdldEZDRCh0ZXh0LCB0ZXh0b2Zmc2V0ICsrKSAKCSAgICAgICAgICAgICAgICAJCT4+IFNFQ09ORF9MQVNUX0JZVEVfU0hJRlRfKSA9PSAwKSB7CgkgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICAgICAgcmV0dXJuIHRleHQuZ2V0RW5kSW5kZXgoKTsKCSAgICB9CgkgICAgcmV0dXJuIHRleHRvZmZzZXQ7Cgl9CgkKCS8qKgoJICogR2V0cyB0aGUgbmV4dCBiYXNlIGNoYXJhY3RlciBvZmZzZXQgZGVwZW5kaW5nIG9uIHRoZSBzdHJpbmcgc2VhcmNoIAoJICogcGF0dGVybiBkYXRhCgkgKiBAcGFyYW0gdGV4dG9mZnNldCBvbmUgb2Zmc2V0IGF3YXkgZnJvbSB0aGUgbGFzdCBjaGFyYWN0ZXIKCSAqICAgICAgICAgICAgICAgICAgIHRvIHNlYXJjaCBmb3IuCgkgKiBAcmV0dXJuIHN0YXJ0IGluZGV4IG9mIHRoZSBuZXh0IGJhc2UgY2hhcmFjdGVyIG9yIHRoZSBjdXJyZW50IG9mZnNldAoJICogICAgICAgICBpZiB0aGUgY3VycmVudCBjaGFyYWN0ZXIgaXMgY29udGFpbnMgYSBiYXNlIGNoYXJhY3Rlci4KCSAqLwoJcHJpdmF0ZSBmaW5hbCBpbnQgZ2V0TmV4dEJhc2VPZmZzZXQoaW50IHRleHRvZmZzZXQpCgl7CgkgICAgaWYgKG1fcGF0dGVybl8ubV9oYXNTdWZmaXhBY2NlbnRzXyAKCSAgICAJJiYgdGV4dG9mZnNldCA8IG1fdGV4dExpbWl0T2Zmc2V0XykgewogICAgICAgICAgICB0YXJnZXRUZXh0LnNldEluZGV4KHRleHRvZmZzZXQpOwogICAgICAgICAgICB0YXJnZXRUZXh0LnByZXZpb3VzKCk7CiAgICAgICAgICAgIGlmICgoZ2V0RkNEKHRhcmdldFRleHQsIHRhcmdldFRleHQuZ2V0SW5kZXgoKSkgJiBMQVNUX0JZVEVfTUFTS18pICE9IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiBnZXROZXh0QmFzZU9mZnNldCh0YXJnZXRUZXh0LCB0ZXh0b2Zmc2V0KTsKICAgICAgICAgICAgfQoJICAgIH0KCSAgICByZXR1cm4gdGV4dG9mZnNldDsKCX0KCQoJLyoqCgkgKiBTaGlmdGluZyB0aGUgY29sbGF0aW9uIGVsZW1lbnQgaXRlcmF0b3IgcG9zaXRpb24gZm9yd2FyZCB0byBwcmVwYXJlIGZvcgoJICogYSBmb2xsb3dpbmcgbWF0Y2guIElmIHRoZSBsYXN0IGNoYXJhY3RlciBpcyBhIHVuc2FmZSBjaGFyYWN0ZXIsIHdlJ2xsIAoJICogb25seSBzaGlmdCBieSAxIHRvIGNhcHR1cmUgY29udHJhY3Rpb25zLCBub3JtYWxpemF0aW9uIGV0Yy4KCSAqIEludGVybmFsIG1ldGhvZCwgc3RhdHVzIGFzc3VtZWQgdG8gYmUgc3VjY2Vzcy4KCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IHN0YXJ0IHRleHQgcG9zaXRpb24gdG8gZG8gc2VhcmNoCgkgKiBAcGFyYW0gY2UgdGhlIHRleHQgY2Ugd2hpY2ggZmFpbGVkIHRoZSBtYXRjaC4KCSAqIEBwYXJhbSBwYXR0ZXJuY2VpbmRleCBpbmRleCBvZiB0aGUgY2Ugd2l0aGluIHRoZSBwYXR0ZXJuIGNlIGJ1ZmZlciB3aGljaAoJICogICAgICAgIGZhaWxlZCB0aGUgbWF0Y2gKCSAqIEByZXR1cm4gZmluYWwgb2Zmc2V0CgkgKi8KCXByaXZhdGUgaW50IHNoaWZ0Rm9yd2FyZChpbnQgdGV4dG9mZnNldCwgaW50IGNlLCBpbnQgcGF0dGVybmNlaW5kZXgpCgkJCQkJCQkJCQoJewoJICAgIGlmIChpc092ZXJsYXBwaW5nKCkpIHsKCSAgICAgICAgaWYgKHRleHRvZmZzZXQgPiBtX3RleHRCZWdpbk9mZnNldF8pIHsKCSAgICAgICAgICAgIHRleHRvZmZzZXQgKys7CgkgICAgICAgIH0KCSAgICAgICAgZWxzZSB7CgkgICAgICAgICAgICB0ZXh0b2Zmc2V0ID0gbV9wYXR0ZXJuXy5tX2RlZmF1bHRTaGlmdFNpemVfOwoJICAgICAgICB9CgkgICAgfQoJICAgIGVsc2UgewoJICAgICAgICBpZiAoY2UgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewoJICAgICAgICAgICAgaW50IHNoaWZ0ID0gbV9wYXR0ZXJuXy5tX3NoaWZ0X1toYXNoKGNlKV07CgkgICAgICAgICAgICAvLyB0aGlzIGlzIHRvIGFkanVzdCBmb3IgY2hhcmFjdGVycyBpbiB0aGUgbWlkZGxlIG9mIHRoZSAKCSAgICAgICAgICAgIC8vIHN1YnN0cmluZyBmb3IgbWF0Y2hpbmcgdGhhdCBmYWlsZWQuCgkgICAgICAgICAgICBpbnQgYWRqdXN0ID0gbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyAtIHBhdHRlcm5jZWluZGV4OwoJICAgICAgICAgICAgaWYgKGFkanVzdCA+IDEgJiYgc2hpZnQgPj0gYWRqdXN0KSB7CgkgICAgICAgICAgICAgICAgc2hpZnQgLT0gYWRqdXN0IC0gMTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHRleHRvZmZzZXQgKz0gc2hpZnQ7CgkgICAgICAgIH0KCSAgICAgICAgZWxzZSB7CgkgICAgICAgICAgICB0ZXh0b2Zmc2V0ICs9IG1fcGF0dGVybl8ubV9kZWZhdWx0U2hpZnRTaXplXzsKCSAgICAgICAgfQoJICAgIH0KCSAgICAgCiAgICAgICAgdGV4dG9mZnNldCA9IGdldE5leHRCYXNlT2Zmc2V0KHRleHRvZmZzZXQpOwoJICAgIC8vIGNoZWNrIGZvciB1bnNhZmUgY2hhcmFjdGVycwoJICAgIC8vICogaWYgaXQgaXMgdGhlIHN0YXJ0IG9yIG1pZGRsZSBvZiBhIGNvbnRyYWN0aW9uOiB0byBiZSBkb25lIGFmdGVyIAoJICAgIC8vICAgYSBpbml0aWFsIG1hdGNoIGlzIGZvdW5kCgkgICAgLy8gKiB0aGFpIG9yIGxhbyBiYXNlIGNvbnNvbmFudCBjaGFyYWN0ZXI6IHNpbWlsYXIgdG8gY29udHJhY3Rpb24KCSAgICAvLyAqIGhpZ2ggc3Vycm9nYXRlIGNoYXJhY3Rlcjogc2ltaWxhciB0byBjb250cmFjdGlvbgoJICAgIC8vICogbmV4dCBjaGFyYWN0ZXIgaXMgYSBhY2NlbnQ6IHNoaWZ0IHRvIHRoZSBuZXh0IGJhc2UgY2hhcmFjdGVyCgkgICAgcmV0dXJuIHRleHRvZmZzZXQ7Cgl9CgkKCS8qKgoJICogR2V0cyB0aGUgb2Zmc2V0IHRvIHRoZSBuZXh0IHNhZmUgcG9pbnQgaW4gdGV4dC4KCSAqIGllLiBub3QgdGhlIG1pZGRsZSBvZiBhIGNvbnRyYWN0aW9uLCBzd2FwcGFibGUgY2hhcmFjdGVycyBvciAKCSAqIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVycy4KCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IG9mZnNldCBpbiBzdHJpbmcKCSAqIEBwYXJhbSBlbmQgb2Zmc2V0IGluIHN0cmluZwoJICogQHJldHVybiBvZmZzZXQgdG8gdGhlIG5leHQgc2FmZSBjaGFyYWN0ZXIKCSAqLwoJcHJpdmF0ZSBmaW5hbCBpbnQgZ2V0TmV4dFNhZmVPZmZzZXQoaW50IHRleHRvZmZzZXQsIGludCBlbmQpCgl7CgkgICAgaW50IHJlc3VsdCA9IHRleHRvZmZzZXQ7IC8vIGZpcnN0IGNvbnRyYWN0aW9uIGNoYXJhY3RlcgoJICAgIHRhcmdldFRleHQuc2V0SW5kZXgocmVzdWx0KTsKCSAgICB3aGlsZSAocmVzdWx0ICE9IGVuZCAmJiAKCSAgICAJbV9jb2xsYXRvcl8uaXNVbnNhZmUodGFyZ2V0VGV4dC5jdXJyZW50KCkpKSB7CgkgICAgICAgCXJlc3VsdCArKzsKCSAgICAgICAJdGFyZ2V0VGV4dC5zZXRJbmRleChyZXN1bHQpOwoJICAgIH0KCSAgICByZXR1cm4gcmVzdWx0OyAKCX0KCQoJLyoqIAoJICogVGhpcyBjaGVja3MgZm9yIGFjY2VudHMgaW4gdGhlIHBvdGVudGlhbCBtYXRjaCBzdGFydGVkIHdpdGggYSBjb21wb3NpdGUgCgkgKiBjaGFyYWN0ZXIuCgkgKiBUaGlzIGlzIHJlYWxseSBwYWluZnVsLi4uIHdlIGhhdmUgdG8gY2hlY2sgdGhhdCBjb21wb3NpdGUgY2hhcmFjdGVyIGRvIAoJICogbm90IGhhdmUgYW55IGV4dHJhIGFjY2VudHMuIFdlIGhhdmUgdG8gbm9ybWFsaXplIHRoZSBwb3RlbnRpYWwgbWF0Y2ggYW5kIAoJICogZmluZCB0aGUgaW1tZWRpYXRlIGRlY29tcG9zZWQgY2hhcmFjdGVyIGJlZm9yZSB0aGUgbWF0Y2guCgkgKiBUaGUgZmlyc3QgY29tcG9zaXRlIGNoYXJhY3RlciB3b3VsZCBoYXZlIGJlZW4gdGFrZW4gY2FyZSBvZiBieSB0aGUgZmNkIAoJICogY2hlY2tzIGluIGNoZWNrRm9yd2FyZEV4YWN0TWF0Y2guCgkgKiBUaGlzIGlzIHRoZSBzbG93IHBhdGggYWZ0ZXIgdGhlIGZjZCBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGFuZCAKCSAqIHRoZSBsYXN0IGNoYXJhY3RlciBoYXMgYmVlbiBjaGVja2VkIGJ5IGNoZWNrRm9yd2FyZEV4YWN0TWF0Y2ggYW5kIHdlIAoJICogZGV0ZXJtaW5lIHRoYXQgdGhlIHBvdGVudGlhbCBtYXRjaCBoYXMgZXh0cmEgbm9uLWlnbm9yYWJsZSBwcmVjZWRpbmcKCSAqIGNlcy4KCSAqIEUuZy4gbG9va2luZyBmb3IgXHUwMzAxIGFjdXRlIGluIFx1MDFGQSBBIHJpbmcgYWJvdmUgYW5kIGFjdXRlLCAKCSAqIGNoZWNrRXh0cmFNYXRjaEFjY2VudCBzaG91bGQgZmFpbCBzaW5jZSB0aGVyZSBpcyBhIG1pZGRsZSByaW5nIGluIAoJICogXHUwMUZBIE5vdGUgaGVyZSB0aGF0IGFjY2VudHMgY2hlY2tpbmcgYXJlIHNsb3cgYW5kIGNhdXRpb25lZCBpbiB0aGUgQVBJIAoJICogZG9jcy4KCSAqIEludGVybmFsIG1ldGhvZCwgc3RhdHVzIGFzc3VtZWQgdG8gYmUgYSBzdWNjZXNzLCBjYWxsZXIgc2hvdWxkIGNoZWNrIAoJICogc3RhdHVzIGJlZm9yZSBjYWxsaW5nIHRoaXMgbWV0aG9kCgkgKiBAcGFyYW0gc3RhcnQgaW5kZXggb2YgdGhlIHBvdGVudGlhbCB1bmZyaWVuZGx5IGNvbXBvc2l0ZSBjaGFyYWN0ZXIKCSAqIEBwYXJhbSBlbmQgaW5kZXggb2YgdGhlIHBvdGVudGlhbCB1bmZyaWVuZGx5IGNvbXBvc2l0ZSBjaGFyYWN0ZXIKCSAqIEByZXR1cm4gdHJ1ZSBpZiB0aGVyZSBpcyBub24taWdub3JhYmxlIGFjY2VudHMgYmVmb3JlIGF0IHRoZSBiZWdpbm5pbmcKCSAqICAgICAgICAgICAgICBvZiB0aGUgbWF0Y2gsIGZhbHNlIG90aGVyd2lzZS4KCSAqLwoJcHJpdmF0ZSBmaW5hbCBib29sZWFuIGNoZWNrRXh0cmFNYXRjaEFjY2VudHMoaW50IHN0YXJ0LCBpbnQgZW5kKQoJewoJICAgIGJvb2xlYW4gcmVzdWx0ID0gZmFsc2U7CgkgICAgaWYgKG1fcGF0dGVybl8ubV9oYXNQcmVmaXhBY2NlbnRzXykgewoJICAgICAgICB0YXJnZXRUZXh0LnNldEluZGV4KHN0YXJ0KTsKCSAgICAgICAgCgkgICAgICAgIGlmIChVVEYxNi5pc0xlYWRTdXJyb2dhdGUodGFyZ2V0VGV4dC5uZXh0KCkpKSB7CgkgICAgICAgIAlpZiAoIVVURjE2LmlzVHJhaWxTdXJyb2dhdGUodGFyZ2V0VGV4dC5uZXh0KCkpKSB7CgkgICAgICAgIAkJdGFyZ2V0VGV4dC5wcmV2aW91cygpOwoJICAgICAgICAJfQoJICAgICAgICB9CgkgICAgICAgIC8vIHdlIGFyZSBvbmx5IGNvbmNlcm5lZCB3aXRoIHRoZSBmaXJzdCBjb21wb3NpdGUgY2hhcmFjdGVyCgkgICAgICAgIFN0cmluZyBzdHIgPSBnZXRTdHJpbmcodGFyZ2V0VGV4dCwgc3RhcnQsIGVuZCk7CgkgICAgICAgIGlmIChOb3JtYWxpemVyLnF1aWNrQ2hlY2soc3RyLCBOb3JtYWxpemVyLk5GRCkgCgkgICAgICAgIAkJCQkJCQkJCQk9PSBOb3JtYWxpemVyLk5PKSB7CgkgICAgICAgICAgICBpbnQgc2FmZW9mZnNldCA9IGdldE5leHRTYWZlT2Zmc2V0KHN0YXJ0LCBlbmQpOwoJICAgICAgICAgICAgaWYgKHNhZmVvZmZzZXQgIT0gZW5kKSB7CgkgICAgICAgICAgICAgICAgc2FmZW9mZnNldCArKzsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIFN0cmluZyBkZWNvbXAgPSBOb3JtYWxpemVyLmRlY29tcG9zZSgKCSAgICAgICAgICAgIAkJCQlzdHIuc3Vic3RyaW5nKDAsIHNhZmVvZmZzZXQgLSBzdGFydCksIGZhbHNlKTsKCSAgICAgICAgICAgIG1fdXRpbENvbEVJdGVyXy5zZXRUZXh0KGRlY29tcCk7CgkgICAgICAgICAgICBpbnQgZmlyc3RjZSA9IG1fcGF0dGVybl8ubV9DRV9bMF07CgkgICAgICAgICAgICBib29sZWFuIGlnbm9yYWJsZSA9IHRydWU7CgkgICAgICAgICAgICBpbnQgY2UgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFOwoJICAgICAgICAgICAgaW50IG9mZnNldCA9IDA7CgkgICAgICAgICAgICB3aGlsZSAoY2UgIT0gZmlyc3RjZSkgewoJICAgICAgICAgICAgCW9mZnNldCA9IG1fdXRpbENvbEVJdGVyXy5nZXRPZmZzZXQoKTsKCSAgICAgICAgICAgICAgICBpZiAoY2UgIT0gZmlyc3RjZSAKCSAgICAgICAgICAgICAgICAJJiYgY2UgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgICAgICAgICBpZ25vcmFibGUgPSBmYWxzZTsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgY2UgPSBtX3V0aWxDb2xFSXRlcl8ubmV4dCgpOwoJICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbV91dGlsQ29sRUl0ZXJfLnNldEV4YWN0T2Zmc2V0KG9mZnNldCk7IC8vIGJhY2sgdXAgMSB0byB0aGUgCiAgICAgICAgICAgICAgICBtX3V0aWxDb2xFSXRlcl8ucHJldmlvdXMoKTsgICAgICAgICAgICAgLy8gcmlnaHQgb2Zmc2V0CiAgICAgICAgICAgICAgICBvZmZzZXQgPSBtX3V0aWxDb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CiAgICAgICAgICAgICAgICByZXN1bHQgPSAhaWdub3JhYmxlICYmIChVQ2hhcmFjdGVyLmdldENvbWJpbmluZ0NsYXNzKAoJICAgICAgICAgICAgCQkJCQkJCVVURjE2LmNoYXJBdChkZWNvbXAsIG9mZnNldCkpICE9IDApOwoJICAgICAgICB9CgkgICAgfQoJCgkgICAgcmV0dXJuIHJlc3VsdDsKCX0KCQoJLyoqCgkqIFVzZWQgYnkgZXhhY3QgbWF0Y2hlcywgY2hlY2tzIGlmIHRoZXJlIGFyZSBhY2NlbnRzIGJlZm9yZSB0aGUgbWF0Y2guIAoJKiBUaGlzIGlzIHJlYWxseSBwYWluZnVsLi4uIHdlIGhhdmUgdG8gY2hlY2sgdGhhdCBjb21wb3NpdGUgY2hhcmFjdGVycyBhdAoJKiB0aGUgc3RhcnQgb2YgdGhlIG1hdGNoZXMgaGF2ZSB0byBub3QgaGF2ZSBhbnkgZXh0cmEgYWNjZW50cy4gCgkqIFdlIGNoZWNrIHRoZSBGQ0Qgb2YgdGhlIGNoYXJhY3RlciBmaXJzdCwgaWYgaXQgc3RhcnRzIHdpdGggYW4gYWNjZW50IGFuZCAKCSogdGhlIGZpcnN0IHBhdHRlcm4gY2UgZG9lcyBub3QgbWF0Y2ggdGhlIGZpcnN0IGNlIG9mIHRoZSBjaGFyYWN0ZXIsIHdlIAoJKiBiYWlsLgoJKiBPdGhlcndpc2Ugd2UgdHJ5IG5vcm1hbGl6aW5nIHRoZSBmaXJzdCBjb21wb3NpdGUgCgkqIGNoYXJhY3RlciBhbmQgZmluZCB0aGUgaW1tZWRpYXRlIGRlY29tcG9zZWQgY2hhcmFjdGVyIGJlZm9yZSB0aGUgbWF0Y2ggdG8gCgkqIHNlZSBpZiBpdCBpcyBhbiBub24taWdub3JhYmxlIGFjY2VudC4KCSogTm93IG5vcm1hbGl6aW5nIHRoZSBmaXJzdCBjb21wb3NpdGUgY2hhcmFjdGVyIGlzIGVub3VnaCBiZWNhdXNlIHdlIGVuc3VyZSAKCSogdGhhdCB3aGVuIHRoZSBtYXRjaCBpcyBwYXNzZWQgaW4gaGVyZSB3aXRoIGV4dHJhIGJlZ2lubmluZyBjZXMsIHRoZSAKCSogZmlyc3Qgb3IgbGFzdCBjZSB0aGF0IG1hdGNoIGhhcyB0byBvY2N1ciB3aXRoaW4gdGhlIGZpcnN0IGNoYXJhY3Rlci4KCSogRS5nLiBsb29raW5nIGZvciBcdTAzMDEgYWN1dGUgaW4gXHUwMUZBIEEgcmluZyBhYm92ZSBhbmQgYWN1dGUsIAoJKiBjaGVja0V4dHJhTWF0Y2hBY2NlbnQgc2hvdWxkIGZhaWwgc2luY2UgdGhlcmUgaXMgYSBtaWRkbGUgcmluZyBpbiBcdTAxRkEKCSogTm90ZSBoZXJlIHRoYXQgYWNjZW50cyBjaGVja2luZyBhcmUgc2xvdyBhbmQgY2F1dGlvbmVkIGluIHRoZSBBUEkgZG9jcy4KCSogQHBhcmFtIHN0YXJ0IG9mZnNldCAKCSogQHBhcmFtIGVuZCBvZmZzZXQKCSogQHJldHVybiB0cnVlIGlmIHRoZXJlIGFyZSBhY2NlbnRzIG9uIGVpdGhlciBzaWRlIG9mIHRoZSBtYXRjaCwgCgkqICAgICAgICAgZmFsc2Ugb3RoZXJ3aXNlCgkqLwoJcHJpdmF0ZSBmaW5hbCBib29sZWFuIGhhc0FjY2VudHNCZWZvcmVNYXRjaChpbnQgc3RhcnQsIGludCBlbmQpIAoJewoJICAgIGlmIChtX3BhdHRlcm5fLm1faGFzUHJlZml4QWNjZW50c18pIHsKCSAgICAgICAgLy8gd2UgaGF2ZSBiZWVuIGl0ZXJhdGluZyBmb3J3YXJkcyBwcmV2aW91c2x5CgkgICAgICAgIGJvb2xlYW4gaWdub3JhYmxlID0gdHJ1ZTsKCSAgICAgICAgaW50IGZpcnN0Y2UgPSBtX3BhdHRlcm5fLm1fQ0VfWzBdOwoJCQltX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldChzdGFydCk7CgkgICAgICAgIGludCBjZSAgPSBnZXRDRShtX2NvbEVJdGVyXy5uZXh0KCkpOwoJICAgICAgICB3aGlsZSAoY2UgIT0gZmlyc3RjZSkgewoJICAgICAgICAgICAgaWYgKGNlICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgICAgICBpZ25vcmFibGUgPSBmYWxzZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGNlID0gZ2V0Q0UobV9jb2xFSXRlcl8ubmV4dCgpKTsKCSAgICAgICAgfQoJICAgICAgICBpZiAoIWlnbm9yYWJsZSAmJiBtX2NvbEVJdGVyXy5pc0luQnVmZmVyKCkpIHsKCSAgICAgICAgICAgIC8vIHdpdGhpbiBub3JtYWxpemF0aW9uIGJ1ZmZlciwgZGlzY29udGlndW91cyBoYW5kbGVkIGhlcmUKCSAgICAgICAgICAgIHJldHVybiB0cnVlOwoJICAgICAgICB9CgkKCSAgICAgICAgLy8gd2l0aGluIHRleHQKCSAgICAgICAgYm9vbGVhbiBhY2NlbnQgPSAoZ2V0RkNEKHRhcmdldFRleHQsIHN0YXJ0KSA+PiBTRUNPTkRfTEFTVF9CWVRFX1NISUZUXykKCSAgICAgICAgCQkJCQkJCQkJCQkhPSAwOyAKCSAgICAgICAgaWYgKCFhY2NlbnQpIHsKCSAgICAgICAgICAgIHJldHVybiBjaGVja0V4dHJhTWF0Y2hBY2NlbnRzKHN0YXJ0LCBlbmQpOwoJICAgICAgICB9CgkgICAgICAgIGlmICghaWdub3JhYmxlKSB7CgkgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCSAgICAgICAgfQoJICAgICAgICBpZiAoc3RhcnQgPiBtX3RleHRCZWdpbk9mZnNldF8pIHsKCSAgICAgICAgCXRhcmdldFRleHQuc2V0SW5kZXgoc3RhcnQpOwoJICAgICAgICAJdGFyZ2V0VGV4dC5wcmV2aW91cygpOwoJICAgICAgICAgICAgaWYgKChnZXRGQ0QodGFyZ2V0VGV4dCwgdGFyZ2V0VGV4dC5nZXRJbmRleCgpKSAmIExBU1RfQllURV9NQVNLXykgCgkgICAgICAgICAgICAJCQkJCQkJCQkJCQkJCSE9IDApIHsKCSAgICAgICAgICAgICAgICBtX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldChzdGFydCk7CgkgICAgICAgICAgICAgICAgY2UgPSBtX2NvbEVJdGVyXy5wcmV2aW91cygpOwoJICAgICAgICAgICAgICAgIGlmIChjZSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSIAoJICAgICAgICAgICAgICAgIAkmJiBjZSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CgkgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgIH0KCSAgCgkgICAgcmV0dXJuIGZhbHNlOwoJfQoJCgkvKioKCSAqIFVzZWQgYnkgZXhhY3QgbWF0Y2hlcywgY2hlY2tzIGlmIHRoZXJlIGFyZSBhY2NlbnRzIGJvdW5kaW5nIHRoZSBtYXRjaC4KCSAqIE5vdGUgdGhpcyBpcyB0aGUgaW5pdGlhbCBib3VuZGFyeSBjaGVjay4gSWYgdGhlIHBvdGVudGlhbCBtYXRjaAoJICogc3RhcnRzIG9yIGVuZHMgd2l0aCBjb21wb3NpdGUgY2hhcmFjdGVycywgdGhlIGFjY2VudHMgaW4gdGhvc2UKCSAqIGNoYXJhY3RlcnMgd2lsbCBiZSBkZXRlcm1pbmVkIGxhdGVyLgoJICogTm90IGRvaW5nIGJhY2t3YXJkcyBpdGVyYXRpb24gaGVyZSwgc2luY2UgZGlzY29udGlndW9zIGNvbnRyYWN0aW9uIGZvciAKCSAqIGJhY2t3YXJkcyBjb2xsYXRpb24gZWxlbWVudCBpdGVyYXRvciwgdXNlIHVwIHRvbyBtYW55IGNoYXJhY3RlcnMuCgkgKiBFLmcuIGxvb2tpbmcgZm9yIFx1MDMwQSByaW5nIGluIFx1MDFGQSBBIHJpbmcgYWJvdmUgYW5kIGFjdXRlLCAKCSAqIHNob3VsZCBmYWlsIHNpbmNlIHRoZXJlIGlzIGEgYWN1dGUgYXQgdGhlIGVuZCBvZiBcdTAxRkEKCSAqIE5vdGUgaGVyZSB0aGF0IGFjY2VudHMgY2hlY2tpbmcgYXJlIHNsb3cgYW5kIGNhdXRpb25lZCBpbiB0aGUgQVBJIGRvY3MuCgkgKiBAcGFyYW0gc3RhcnQgb2Zmc2V0IG9mIG1hdGNoCgkgKiBAcGFyYW0gZW5kIGVuZCBvZmZzZXQgb2YgdGhlIG1hdGNoCgkgKiBAcmV0dXJuIHRydWUgaWYgdGhlcmUgYXJlIGFjY2VudHMgb24gZWl0aGVyIHNpZGUgb2YgdGhlIG1hdGNoLCAKCSAqICAgICAgICAgZmFsc2Ugb3RoZXJ3aXNlCgkgKi8KCXByaXZhdGUgZmluYWwgYm9vbGVhbiBoYXNBY2NlbnRzQWZ0ZXJNYXRjaChpbnQgc3RhcnQsIGludCBlbmQpIAoJewoJICAgIGlmIChtX3BhdHRlcm5fLm1faGFzU3VmZml4QWNjZW50c18pIHsKCSAgICAJdGFyZ2V0VGV4dC5zZXRJbmRleChlbmQpOwoJICAgICAgICBpZiAoZW5kID4gbV90ZXh0QmVnaW5PZmZzZXRfIAoJICAgICAgICAJJiYgVVRGMTYuaXNUcmFpbFN1cnJvZ2F0ZSh0YXJnZXRUZXh0LnByZXZpb3VzKCkpKSB7CgkgICAgICAgIAlpZiAodGFyZ2V0VGV4dC5nZXRJbmRleCgpID4gbV90ZXh0QmVnaW5PZmZzZXRfICYmCgkgICAgICAgIAkJIVVURjE2LmlzTGVhZFN1cnJvZ2F0ZSh0YXJnZXRUZXh0LnByZXZpb3VzKCkpKSB7CgkgICAgICAgIAkJdGFyZ2V0VGV4dC5uZXh0KCk7CgkgICAgICAgIAl9CgkgICAgICAgIH0KCSAgICAgICAgaWYgKChnZXRGQ0QodGFyZ2V0VGV4dCwgdGFyZ2V0VGV4dC5nZXRJbmRleCgpKSAmIExBU1RfQllURV9NQVNLXykgIT0gMCkgewoJICAgICAgICAgICAgaW50IGZpcnN0Y2UgID0gbV9wYXR0ZXJuXy5tX0NFX1swXTsKCSAgICAgICAgICAgIG1fY29sRUl0ZXJfLnNldEV4YWN0T2Zmc2V0KHN0YXJ0KTsKCSAgICAgICAgICAgIHdoaWxlIChnZXRDRShtX2NvbEVJdGVyXy5uZXh0KCkpICE9IGZpcnN0Y2UpIHsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGludCBjb3VudCA9IDE7CgkgICAgICAgICAgICB3aGlsZSAoY291bnQgPCBtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfKSB7CgkgICAgICAgICAgICAgICAgaWYgKGdldENFKG1fY29sRUl0ZXJfLm5leHQoKSkgCgkgICAgICAgICAgICAgICAgCT09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgICAgICAJY291bnQgLS07CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgIGNvdW50ICsrOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaW50IGNlID0gZ2V0Q0UobV9jb2xFSXRlcl8ubmV4dCgpKTsKCSAgICAgICAgICAgIGlmIChjZSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSIAoJICAgICAgICAgICAgCQkJJiYgY2UgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgICAgIGlmIChtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKSA8PSBlbmQpIHsKCSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgIGlmICgoZ2V0RkNEKHRhcmdldFRleHQsIGVuZCkgPj4gU0VDT05EX0xBU1RfQllURV9TSElGVF8pIAoJICAgICAgICAgICAgICAgIAkhPSAwKSB7CgkgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgIH0KCSAgICByZXR1cm4gZmFsc2U7Cgl9CgkKCS8qKgoJKiBDaGVja3MgaWYgdGhlIG9mZnNldCBydW5zIG91dCBvZiB0aGUgdGV4dCBzdHJpbmcgcmFuZ2UKCSogQHBhcmFtIHRleHRzdGFydCBvZmZzZXQgb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgcmFuZ2UKCSogQHBhcmFtIHRleHRsaW1pdCBsaW1pdCBvZmZzZXQgb2YgdGhlIHRleHQgc3RyaW5nIHJhbmdlCgkqIEBwYXJhbSBvZmZzZXQgdG8gdGVzdAoJKiBAcmV0dXJuIHRydWUgaWYgb2Zmc2V0IGlzIG91dCBvZiBib3VuZHMsIGZhbHNlIG90aGVyd2lzZQoJKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gaXNPdXRPZkJvdW5kcyhpbnQgdGV4dHN0YXJ0LCBpbnQgdGV4dGxpbWl0LCAKCQkJCQkJCQkJCQkJaW50IG9mZnNldCkKCXsKCSAgICByZXR1cm4gb2Zmc2V0IDwgdGV4dHN0YXJ0IHx8IG9mZnNldCA+IHRleHRsaW1pdDsKCX0KCQoJLyoqCgkgKiBDaGVja3MgZm9yIGlkZW50aWNhbCBtYXRjaAoJICogQHBhcmFtIHN0cnNyY2ggc3RyaW5nIHNlYXJjaCBkYXRhCgkgKiBAcGFyYW0gc3RhcnQgb2Zmc2V0IG9mIHBvc3NpYmxlIG1hdGNoCgkgKiBAcGFyYW0gZW5kIG9mZnNldCBvZiBwb3NzaWJsZSBtYXRjaAoJICogQHJldHVybiB0cnVlIGlmIGlkZW50aWNhbCBtYXRjaCBpcyBmb3VuZAoJICovCglwcml2YXRlIGZpbmFsIGJvb2xlYW4gY2hlY2tJZGVudGljYWwoaW50IHN0YXJ0LCBpbnQgZW5kKSAKCXsKCSAgICBpZiAobV9jb2xsYXRvcl8uZ2V0U3RyZW5ndGgoKSAhPSBDb2xsYXRvci5JREVOVElDQUwpIHsKCSAgICAgICAgcmV0dXJuIHRydWU7CgkgICAgfQoJCgkJU3RyaW5nIHRleHRzdHIgPSBnZXRTdHJpbmcodGFyZ2V0VGV4dCwgc3RhcnQsIGVuZCAtIHN0YXJ0KTsKCQlpZiAoTm9ybWFsaXplci5xdWlja0NoZWNrKHRleHRzdHIsIE5vcm1hbGl6ZXIuTkZEKSAKCSAgICAgICAgCQkJCQkJCQkJCT09IE5vcm1hbGl6ZXIuTk8pIHsKCSAgICAgICAgdGV4dHN0ciA9IE5vcm1hbGl6ZXIuZGVjb21wb3NlKHRleHRzdHIsIGZhbHNlKTsKCSAgICB9CgkgICAgU3RyaW5nIHBhdHRlcm5zdHIgPSBtX3BhdHRlcm5fLnRhcmdldFRleHQ7CgkgICAgaWYgKE5vcm1hbGl6ZXIucXVpY2tDaGVjayhwYXR0ZXJuc3RyLCBOb3JtYWxpemVyLk5GRCkgCgkgICAgICAgIAkJCQkJCQkJCQk9PSBOb3JtYWxpemVyLk5PKSB7CgkgICAgICAgIHBhdHRlcm5zdHIgPSBOb3JtYWxpemVyLmRlY29tcG9zZShwYXR0ZXJuc3RyLCBmYWxzZSk7CgkgICAgfQoJICAgIHJldHVybiB0ZXh0c3RyLmVxdWFscyhwYXR0ZXJuc3RyKTsKCX0KCQoJLyoqCgkgKiBDaGVja3MgdG8gc2VlIGlmIHRoZSBtYXRjaCBpcyByZXBlYXRlZAoJICogQHBhcmFtIHN0YXJ0IG5ldyBtYXRjaCBzdGFydCBpbmRleAoJICogQHBhcmFtIGxpbWl0IG5ldyBtYXRjaCBsaW1pdCBpbmRleAoJICogQHJldHVybiB0cnVlIGlmIHRoZSB0aGUgbWF0Y2ggaXMgcmVwZWF0ZWQsIGZhbHNlIG90aGVyd2lzZQoJICovCglwcml2YXRlIGZpbmFsIGJvb2xlYW4gY2hlY2tSZXBlYXRlZE1hdGNoKGludCBzdGFydCwgaW50IGxpbWl0KQoJewoJICAgIGlmIChtX21hdGNoZWRJbmRleF8gPT0gRE9ORSkgewoJICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgfQogICAgICAgIGludCBlbmQgPSBsaW1pdCAtIDE7IC8vIGxhc3QgY2hhcmFjdGVyIGluIHRoZSBtYXRjaAoJICAgIGludCBsYXN0bWF0Y2hlbmQgPSBtX21hdGNoZWRJbmRleF8gKyBtYXRjaExlbmd0aCAtIDE7IAoJICAgIGlmICghaXNPdmVybGFwcGluZygpKSB7CiAgICAgICAgICAgIHJldHVybiAoc3RhcnQgPj0gbV9tYXRjaGVkSW5kZXhfICYmIHN0YXJ0IDw9IGxhc3RtYXRjaGVuZCkgCiAgICAgICAgICAgICAgICAgICAgfHwgKGVuZCA+PSBtX21hdGNoZWRJbmRleF8gJiYgZW5kIDw9IGxhc3RtYXRjaGVuZCk7CiAgICAgICAgICAgICAgICAgICAgICAKCSAgICB9CgkgICAgcmV0dXJuIHN0YXJ0ID09IG1fbWF0Y2hlZEluZGV4XzsKCX0KCQoJLyoqCgkgKiBDaGVja3MgbWF0Y2ggZm9yIGNvbnRyYWN0aW9uLiAKCSAqIElmIHRoZSBtYXRjaCBlbmRzIHdpdGggYSBwYXJ0aWFsIGNvbnRyYWN0aW9uIHdlIGZhaWwuCgkgKiBJZiB0aGUgbWF0Y2ggc3RhcnRzIHRvbyBmYXIgb2ZmIChiZWNhdXNlIG9mIGJhY2t3YXJkcyBpdGVyYXRpb24pIHdlIHRyeSAKCSAqIHRvIGNoaXAgb2ZmIHRoZSBleHRyYSBjaGFyYWN0ZXJzIGRlcGVuZGluZyBvbiB3aGV0aGVyIGEgYnJlYWtpdGVyYXRvciAKCSAqIGhhcyBiZWVuIHVzZWQuCgkgKiBUZW1wb3JhcnkgdXRpbGl0eSBidWZmZXIgdXNlZCB0byByZXR1cm4gbW9kaWZpZWQgc3RhcnQgYW5kIGVuZC4KCSAqIEBwYXJhbSBzdGFydCBvZmZzZXQgb2YgcG90ZW50aWFsIG1hdGNoLCB0byBiZSBtb2RpZmllZCBpZiBuZWNlc3NhcnkKCSAqIEBwYXJhbSBlbmQgb2Zmc2V0IG9mIHBvdGVudGlhbCBtYXRjaCwgdG8gYmUgbW9kaWZpZWQgaWYgbmVjZXNzYXJ5CgkgKiBAcmV0dXJuIHRydWUgaWYgbWF0Y2ggcGFzc2VzIHRoZSBjb250cmFjdGlvbiB0ZXN0LCBmYWxzZSBvdGhlcndpc2UuCgkgKi8KCXByaXZhdGUgZmluYWwgYm9vbGVhbiBjaGVja05leHRFeGFjdENvbnRyYWN0aW9uTWF0Y2goaW50IHN0YXJ0LCBpbnQgZW5kKSAKCXsKCSAgICAvLyBUaGlzIHBhcnQgY2hlY2tzIGlmIGVpdGhlciBlbmRzIG9mIHRoZSBtYXRjaCBjb250YWlucyBwb3RlbnRpYWwgCgkgICAgLy8gY29udHJhY3Rpb24uIElmIHNvIHdlJ2xsIGhhdmUgdG8gaXRlcmF0ZSB0aHJvdWdoIHRoZW0KCSAgICBjaGFyIGVuZGNoYXIgPSAwOwoJICAgIGlmIChlbmQgPCBtX3RleHRMaW1pdE9mZnNldF8pIHsKCSAgICAJdGFyZ2V0VGV4dC5zZXRJbmRleChlbmQpOwoJICAgIAllbmRjaGFyID0gdGFyZ2V0VGV4dC5jdXJyZW50KCk7CgkgICAgfQoJICAgIGNoYXIgcG9zdHN0YXJ0Y2hhciA9IDA7CgkgICAgaWYgKHN0YXJ0ICsgMSA8IG1fdGV4dExpbWl0T2Zmc2V0XykgewoJICAgIAl0YXJnZXRUZXh0LnNldEluZGV4KHN0YXJ0ICsgMSk7CgkgICAgCXBvc3RzdGFydGNoYXIgPSB0YXJnZXRUZXh0LmN1cnJlbnQoKTsKCSAgICB9CgkgICAgaWYgKG1fY29sbGF0b3JfLmlzVW5zYWZlKGVuZGNoYXIpIAoJICAgIAl8fCBtX2NvbGxhdG9yXy5pc1Vuc2FmZShwb3N0c3RhcnRjaGFyKSkgewoJICAgICAgICAvLyBleHBhbnNpb24gcHJlZml4LCB3aGF0J3MgbGVmdCB0byBpdGVyYXRlCgkgICAgICAgIGludCBidWZmZXJlZENFT2Zmc2V0ID0gbV9jb2xFSXRlcl8ubV9DRUJ1ZmZlck9mZnNldF87CgkgICAgICAgIGJvb2xlYW4gaGFzQnVmZmVyZWRDRSA9IGJ1ZmZlcmVkQ0VPZmZzZXQgPiAwOwoJICAgICAgICBtX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldChzdGFydCk7CgkgICAgICAgIGludCB0ZW1wID0gc3RhcnQ7CgkgICAgICAgIHdoaWxlIChidWZmZXJlZENFT2Zmc2V0ID4gMCkgewoJICAgICAgICAgICAgLy8gZ2V0dGluZyByaWQgb2YgdGhlIHJlZHVuZGFudCBjZSwgY2F1c2VkIGJ5IHNldE9mZnNldC4KCSAgICAgICAgICAgIC8vIHNpbmNlIGJhY2t3YXJkIGNvbnRyYWN0aW9uL2V4cGFuc2lvbiBtYXkgaGF2ZSBleHRyYSBjZXMgaWYgCgkgICAgICAgICAgICAvLyB3ZSBhcmUgaW4gdGhlIG5vcm1hbGl6YXRpb24gYnVmZmVyLCBoYXNBY2NlbnRzQmVmb3JlTWF0Y2ggCgkgICAgICAgICAgICAvLyB3b3VsZCBoYXZlIHRha2VuIGNhcmUgb2YgaXQuCgkgICAgICAgICAgICAvLyBFLmcuIHRoZSBjaGFyYWN0ZXIgXHUwMUZBIHdpbGwgaGF2ZSBhbiBleHBhbnNpb24gb2YgMywgYnV0IAoJICAgICAgICAgICAgLy8gaWYgd2UgYXJlIG9ubHkgbG9va2luZyBmb3IgYWN1dGUgYW5kIHJpbmcgXHUwMzBBIGFuZCBcdTAzMDEsIAoJICAgICAgICAgICAgLy8gd2UnbGwgaGF2ZSB0byBza2lwIHRoZSBmaXJzdCBjZSBpbiB0aGUgZXhwYW5zaW9uIGJ1ZmZlci4KCSAgICAgICAgICAgIG1fY29sRUl0ZXJfLm5leHQoKTsKCSAgICAgICAgICAgIGlmIChtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKSAhPSB0ZW1wKSB7CgkgICAgICAgICAgICAgICAgc3RhcnQgPSB0ZW1wOwoJICAgICAgICAgICAgICAgIHRlbXAgID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBidWZmZXJlZENFT2Zmc2V0IC0tOwoJICAgICAgICB9CgkKCSAgICAgICAgaW50IGNvdW50ID0gMDsKCSAgICAgICAgd2hpbGUgKGNvdW50IDwgbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXykgewoJICAgICAgICAgICAgaW50IGNlID0gZ2V0Q0UobV9jb2xFSXRlcl8ubmV4dCgpKTsKCSAgICAgICAgICAgIGlmIChjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CgkgICAgICAgICAgICAgICAgY29udGludWU7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAoaGFzQnVmZmVyZWRDRSAmJiBjb3VudCA9PSAwIAoJICAgICAgICAgICAgCSYmIG1fY29sRUl0ZXJfLmdldE9mZnNldCgpICE9IHRlbXApIHsKCSAgICAgICAgICAgICAgICBzdGFydCA9IHRlbXA7CgkgICAgICAgICAgICAgICAgdGVtcCAgID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAoY2UgIT0gbV9wYXR0ZXJuXy5tX0NFX1tjb3VudF0pIHsKCSAgICAgICAgICAgICAgICBlbmQgKys7CgkgICAgICAgICAgICAgICAgZW5kID0gZ2V0TmV4dEJhc2VPZmZzZXQoZW5kKTsgIAoJICAgICAgICAgICAgICAgIG1fdXRpbEJ1ZmZlcl9bMF0gPSBzdGFydDsKCSAgICAgICAgICAgICAgICBtX3V0aWxCdWZmZXJfWzFdID0gZW5kOwoJICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGNvdW50ICsrOwoJICAgICAgICB9CgkgICAgfSAKCSAgICBtX3V0aWxCdWZmZXJfWzBdID0gc3RhcnQ7CgkgICAgbV91dGlsQnVmZmVyX1sxXSA9IGVuZDsKCSAgICByZXR1cm4gdHJ1ZTsKCX0KCQoJCgkvKioKCSAqIENoZWNrcyBhbmQgc2V0cyB0aGUgbWF0Y2ggaW5mb3JtYXRpb24gaWYgZm91bmQuCgkgKiBDaGVja3MgCgkgKiA8dWw+CgkgKiA8bGk+IHRoZSBwb3RlbnRpYWwgbWF0Y2ggZG9lcyBub3QgcmVwZWF0IHRoZSBwcmV2aW91cyBtYXRjaAoJICogPGxpPiBib3VuZGFyaWVzIGFyZSBjb3JyZWN0CgkgKiA8bGk+IGV4YWN0IG1hdGNoZXMgaGFzIG5vIGV4dHJhIGFjY2VudHMKCSAqIDxsaT4gaWRlbnRpY2FsIG1hdGNoZXNiCgkgKiA8bGk+IHBvdGVudGlhbCBtYXRjaCBkb2VzIG5vdCBlbmQgaW4gdGhlIG1pZGRsZSBvZiBhIGNvbnRyYWN0aW9uCgkgKiA8L3VsPgoJICogT3RoZXJ3aXNlIHRoZSBvZmZzZXQgd2lsbCBiZSBzaGlmdGVkIHRvIHRoZSBuZXh0IGNoYXJhY3Rlci4KCSAqIFRoZSByZXN1bHQgbV9tYXRjaEluZGV4XyBhbmQgbV9tYXRjaExlbmd0aF8gd2lsbCBiZSBzZXQgdG8gdGhlIHRydW5jYXRlZAoJICogbW9yZSBmaXR0aW5nIHJlc3VsdCB2YWx1ZS4KCSAqIFVzZXMgdGhlIHRlbXBvcmFyeSB1dGlsaXR5IGJ1ZmZlciBmb3Igc3RvcmluZyB0aGUgbW9kaWZpZWQgdGV4dG9mZnNldC4KCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IG9mZnNldCBpbiB0aGUgY29sbGF0aW9uIGVsZW1lbnQgdGV4dC4KCSAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbWF0Y2ggaXMgdmFsaWQsIGZhbHNlIG90aGVyd2lzZQoJICovCglwcml2YXRlIGZpbmFsIGJvb2xlYW4gY2hlY2tOZXh0RXhhY3RNYXRjaChpbnQgdGV4dG9mZnNldCkKCXsKCSAgICBpbnQgc3RhcnQgPSBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKTsgICAgICAgIAoJICAgIGlmICghY2hlY2tOZXh0RXhhY3RDb250cmFjdGlvbk1hdGNoKHN0YXJ0LCB0ZXh0b2Zmc2V0KSkgewoJICAgIAkvLyByZXR1cm5zIHRoZSBtb2RpZmllZCB0ZXh0b2Zmc2V0CgkgICAgCW1fdXRpbEJ1ZmZlcl9bMF0gPSBtX3V0aWxCdWZmZXJfWzFdOwoJICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgfQoJCgkJc3RhcnQgPSBtX3V0aWxCdWZmZXJfWzBdOwoJCXRleHRvZmZzZXQgPSBtX3V0aWxCdWZmZXJfWzFdOwoJICAgIC8vIHRoaXMgdG90YWxseSBtYXRjaGVzLCBob3dldmVyIHdlIG5lZWQgdG8gY2hlY2sgaWYgaXQgaXMgcmVwZWF0aW5nCgkgICAgaWYgKCFpc0JyZWFrVW5pdChzdGFydCwgdGV4dG9mZnNldCkgCgkgICAgCXx8IGNoZWNrUmVwZWF0ZWRNYXRjaChzdGFydCwgdGV4dG9mZnNldCkgCgkgICAgCXx8IGhhc0FjY2VudHNCZWZvcmVNYXRjaChzdGFydCwgdGV4dG9mZnNldCkgCgkgICAgCXx8ICFjaGVja0lkZW50aWNhbChzdGFydCwgdGV4dG9mZnNldCkgCgkgICAgCXx8IGhhc0FjY2VudHNBZnRlck1hdGNoKHN0YXJ0LCB0ZXh0b2Zmc2V0KSkgewoJICAgICAgICB0ZXh0b2Zmc2V0ICsrOwoJICAgICAgICB0ZXh0b2Zmc2V0ID0gZ2V0TmV4dEJhc2VPZmZzZXQodGV4dG9mZnNldCk7ICAKCSAgICAgICAgbV91dGlsQnVmZmVyX1swXSA9IHRleHRvZmZzZXQ7CgkgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICB9CgkgICAgICAgIAoJICAgIC8vIHRvdGFsbHkgbWF0Y2gsIHdlIHdpbGwgZ2V0IHJpZCBvZiB0aGUgZW5kaW5nIGlnbm9yYWJsZXMuCgkgICAgbV9tYXRjaGVkSW5kZXhfICA9IHN0YXJ0OwoJICAgIG1hdGNoTGVuZ3RoID0gdGV4dG9mZnNldCAtIHN0YXJ0OwoJICAgIHJldHVybiB0cnVlOwoJfQoJCgkvKioKCSogR2V0dGluZyB0aGUgcHJldmlvdXMgYmFzZSBjaGFyYWN0ZXIgb2Zmc2V0LCBvciB0aGUgY3VycmVudCBvZmZzZXQgaWYgdGhlIAoJKiBjdXJyZW50IGNoYXJhY3RlciBpcyBhIGJhc2UgY2hhcmFjdGVyCgkqIEBwYXJhbSB0ZXh0IHRoZSBzb3VyY2UgdGV4dCB0byB3b3JrIG9uCgkqIEBwYXJhbSB0ZXh0b2Zmc2V0IG9uZSBvZmZzZXQgYWZ0ZXIgdGhlIGN1cnJlbnQgY2hhcmFjdGVyCgkqIEByZXR1cm4gdGhlIG9mZnNldCBvZiB0aGUgbmV4dCBjaGFyYWN0ZXIgYWZ0ZXIgdGhlIGJhc2UgY2hhcmFjdGVyIG9yIHRoZSAKCSogCQkJZmlyc3QgY29tcG9zZWQgY2hhcmFjdGVyIHdpdGggYWNjZW50cwoJKi8KCXByaXZhdGUgZmluYWwgaW50IGdldFByZXZpb3VzQmFzZU9mZnNldChDaGFyYWN0ZXJJdGVyYXRvciB0ZXh0LCAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdGV4dG9mZnNldCkKCXsKCSAgICBpZiAodGV4dG9mZnNldCA+IG1fdGV4dEJlZ2luT2Zmc2V0XykgewoJICAgICAgICB3aGlsZSAodHJ1ZSkgewoJICAgICAgICAgICAgaW50IHJlc3VsdCA9IHRleHRvZmZzZXQ7CgkgICAgICAgICAgICB0ZXh0LnNldEluZGV4KHJlc3VsdCk7CgkgICAgICAgICAgICBpZiAoVVRGMTYuaXNUcmFpbFN1cnJvZ2F0ZSh0ZXh0LnByZXZpb3VzKCkpKSB7CgkgICAgICAgICAgICAJaWYgKHRleHQuZ2V0SW5kZXgoKSAhPSB0ZXh0LmdldEJlZ2luSW5kZXgoKSAmJgoJICAgICAgICAgICAgCQkhVVRGMTYuaXNMZWFkU3Vycm9nYXRlKHRleHQucHJldmlvdXMoKSkpIHsKCSAgICAgICAgICAgIAkJdGV4dC5uZXh0KCk7CgkgICAgICAgICAgICAJfQoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgdGV4dG9mZnNldCA9IHRleHQuZ2V0SW5kZXgoKTsKCSAgICAgICAgICAgIGNoYXIgZmNkID0gZ2V0RkNEKHRleHQsIHRleHRvZmZzZXQpOwoJICAgICAgICAgICAgaWYgKChmY2QgPj4gU0VDT05EX0xBU1RfQllURV9TSElGVF8pID09IDApIHsKCSAgICAgICAgICAgICAgICBpZiAoKGZjZCAmIExBU1RfQllURV9NQVNLXykgIT0gMCkgewoJICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGV4dG9mZnNldDsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGlmICh0ZXh0b2Zmc2V0ID09IG1fdGV4dEJlZ2luT2Zmc2V0XykgewoJICAgICAgICAgICAgICAgIHJldHVybiBtX3RleHRCZWdpbk9mZnNldF87CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgcmV0dXJuIHRleHRvZmZzZXQ7Cgl9CgkKCS8qKgoJKiBHZXR0aW5nIHRoZSBpbmRleGVzIG9mIHRoZSBhY2NlbnRzIHRoYXQgYXJlIG5vdCBibG9ja2VkIGluIHRoZSBhcmd1bWVudAoJKiBhY2NlbnQgYXJyYXkKCSogQHBhcmFtIGFjY2VudHMgYWNjZW50cyBpbiBuZmQuCgkqIEBwYXJhbSBhY2NlbnRzaW5kZXggYXJyYXkgdG8gc3RvcmUgdGhlIGluZGV4ZXMgb2YgYWNjZW50cyBpbiBhY2NlbnRzIHRoYXQgCgkqIAkJYXJlIG5vdCBibG9ja2VkCgkqIEByZXR1cm4gdGhlIGxlbmd0aCBvZiBwb3B1bGF0ZWQgYWNjZW50c2luZGV4CgkqLwoJcHJpdmF0ZSBpbnQgZ2V0VW5ibG9ja2VkQWNjZW50SW5kZXgoU3RyaW5nQnVmZmVyIGFjY2VudHMsIAoJCQkJCQkJCQkJaW50IGFjY2VudHNpbmRleFtdKQoJewoJICAgIGludCBpbmRleCA9IDA7CgkgICAgaW50IGxlbmd0aCA9IGFjY2VudHMubGVuZ3RoKCk7CgkgICAgaW50IGNjbGFzcyA9IDA7CgkgICAgaW50IHJlc3VsdCA9IDA7CgkgICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSB7CgkgICAgICAgIGludCBjb2RlcG9pbnQgPSBVVEYxNi5jaGFyQXQoYWNjZW50cywgaW5kZXgpOwoJICAgICAgICBpbnQgdGVtcGNsYXNzID0gVUNoYXJhY3Rlci5nZXRDb21iaW5pbmdDbGFzcyhjb2RlcG9pbnQpOwoJICAgICAgICBpZiAodGVtcGNsYXNzICE9IGNjbGFzcykgewoJICAgICAgICAgICAgY2NsYXNzID0gdGVtcGNsYXNzOwoJICAgICAgICAgICAgYWNjZW50c2luZGV4W3Jlc3VsdF0gPSBpbmRleDsKCSAgICAgICAgICAgIHJlc3VsdCArKzsKCSAgICAgICAgfQoJICAgICAgICBpZiAoVUNoYXJhY3Rlci5pc1N1cHBsZW1lbnRhcnkoY29kZXBvaW50KSkgewoJICAgICAgICAJaW5kZXggKz0gMjsKCSAgICAgICAgfQoJICAgICAgICBlbHNlIHsKCSAgICAgICAgCWluZGV4ICsrOwoJICAgICAgICB9CgkgICAgfQoJICAgIGFjY2VudHNpbmRleFtyZXN1bHRdID0gbGVuZ3RoOwoJICAgIHJldHVybiByZXN1bHQ7Cgl9CgoJLyoqCgkgKiBBcHBlbmRzIDMgU3RyaW5nQnVmZmVyL0NoYXJhY3Rlckl0ZXJhdG9yIHRvZ2V0aGVyIGludG8gYSBkZXN0aW5hdGlvbiAKCSAqIHN0cmluZyBidWZmZXIuCgkgKiBAcGFyYW0gc291cmNlMSBzdHJpbmcgYnVmZmVyCgkgKiBAcGFyYW0gc291cmNlMiBjaGFyYWN0ZXIgaXRlcmF0b3IKCSAqIEBwYXJhbSBzdGFydDIgc3RhcnQgb2YgdGhlIGNoYXJhY3RlciBpdGVyYXRvciB0byBtZXJnZQoJICogQHBhcmFtIGVuZDIgZW5kIG9mIHRoZSBjaGFyYWN0ZXIgaXRlcmF0b3IgdG8gbWVyZ2UKCSAqIEBwYXJhbSBzb3VyY2UzIHN0cmluZyBidWZmZXIKCSAqIEByZXR1cm4gYXBwZW5kZWQgc3RyaW5nIGJ1ZmZlcgoJICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdCdWZmZXIgbWVyZ2UoU3RyaW5nQnVmZmVyIHNvdXJjZTEsIAoJCQkJCQkJCQkgCQlDaGFyYWN0ZXJJdGVyYXRvciBzb3VyY2UyLAoJCQkJCQkJCQkgCQlpbnQgc3RhcnQyLCBpbnQgZW5kMiwKCQkJCQkJCQkJIAkJU3RyaW5nQnVmZmVyIHNvdXJjZTMpIAoJewoJCVN0cmluZ0J1ZmZlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CQoJCWlmIChzb3VyY2UxICE9IG51bGwgJiYgc291cmNlMS5sZW5ndGgoKSAhPSAwKSB7CiAgICAgICAgICAgIC8vIGpkayAxLjMuMSBkb2VzIG5vdCBoYXZlIGFwcGVuZChTdHJpbmdCdWZmZXIpIHlldAogICAgICAgICAgICBpZihjb20uaWJtLmljdS5pbXBsLklDVURlYnVnLmlzSkRLMTRPckhpZ2hlcil7CiAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHNvdXJjZTEpOwogICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoc291cmNlMS50b1N0cmluZygpKTsKICAgICAgICAgICAgfQoJCX0KCQlzb3VyY2UyLnNldEluZGV4KHN0YXJ0Mik7CgkJd2hpbGUgKHNvdXJjZTIuZ2V0SW5kZXgoKSA8IGVuZDIpIHsKCQkJcmVzdWx0LmFwcGVuZChzb3VyY2UyLmN1cnJlbnQoKSk7CgkJCXNvdXJjZTIubmV4dCgpOwoJCX0KCQlpZiAoc291cmNlMyAhPSBudWxsICYmIHNvdXJjZTMubGVuZ3RoKCkgIT0gMCkgewoJCQkvLyBqZGsgMS4zLjEgZG9lcyBub3QgaGF2ZSBhcHBlbmQoU3RyaW5nQnVmZmVyKSB5ZXQKICAgICAgICAgICAgaWYoY29tLmlibS5pY3UuaW1wbC5JQ1VEZWJ1Zy5pc0pESzE0T3JIaWdoZXIpewogICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChzb3VyY2UzKTsKICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHNvdXJjZTMudG9TdHJpbmcoKSk7CiAgICAgICAgICAgIH0KCQl9CgkgICAgcmV0dXJuIHJlc3VsdDsKCX0KCQoJLyoqCgkqIFJ1bm5pbmcgdGhyb3VnaCBhIGNvbGxhdGlvbiBlbGVtZW50IGl0ZXJhdG9yIHRvIHNlZSBpZiB0aGUgY29udGVudHMgCgkqIG1hdGNoZXMgcGF0dGVybiBpbiBzdHJpbmcgc2VhcmNoIGRhdGEKCSogQHBhcmFtIGNvbGVpdGVyIGNvbGxhdGlvbiBlbGVtZW50IGl0ZXJhdG9yIHRvIHRlc3QKCSogQHJldHVybiB0cnVlIGlmIGEgbWF0Y2ggaWYgZm91bmQsIGZhbHNlIG90aGVyd2lzZQoJKi8KCXByaXZhdGUgZmluYWwgYm9vbGVhbiBjaGVja0NvbGxhdGlvbk1hdGNoKENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBjb2xlaXRlcikKCXsKCSAgICBpbnQgcGF0dGVybmNlaW5kZXggPSBtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfOwoJICAgIGludCBvZmZzZXQgPSAwOwoJICAgIHdoaWxlIChwYXR0ZXJuY2VpbmRleCA+IDApIHsKCSAgICAgICAgaW50IGNlID0gZ2V0Q0UoY29sZWl0ZXIubmV4dCgpKTsKCSAgICAgICAgaWYgKGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICB9CgkgICAgICAgIGlmIChjZSAhPSBtX3BhdHRlcm5fLm1fQ0VfW29mZnNldF0pIHsKCSAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICAgICAgfQoJICAgICAgICBvZmZzZXQgKys7CgkgICAgICAgIHBhdHRlcm5jZWluZGV4IC0tOwoJICAgIH0KCSAgICByZXR1cm4gdHJ1ZTsKCX0KCQoJLyoqCgkgKiBSZWFycmFuZ2VzIHRoZSBmcm9udCBhY2NlbnRzIHRvIHRyeSBtYXRjaGluZy4KCSAqIFByZWZpeCBhY2NlbnRzIGluIHRoZSB0ZXh0IHdpbGwgYmUgZ3JvdXBlZCBhY2NvcmRpbmcgdG8gdGhlaXIgY29tYmluaW5nIAoJICogY2xhc3MgYW5kIHRoZSBncm91cHMgd2lsbCBiZSBtaXhlZCBhbmQgbWF0Y2hlZCB0byB0cnkgZmluZCB0aGUgcGVyZmVjdCAKCSAqIG1hdGNoIHdpdGggdGhlIHBhdHRlcm4uCgkgKiBTbyBmb3IgaW5zdGFuY2UgbG9va2luZyBmb3IgIlx1MDMwMSIgaW4gIlx1MDMwQVx1MDMwMVx1MDMyNSIKCSAqIHN0ZXAgMTogc3BsaXQgIlx1MDMwQVx1MDMwMSIgaW50byA2IG90aGVyIHR5cGUgb2YgcG90ZW50aWFsIGFjY2VudCAKCSAqIAkJICAgc3Vic3RyaW5ncyAiXHUwMzBBIiwgIlx1MDMwMSIsICJcdTAzMjUiLCAiXHUwMzBBXHUwMzAxIiwgCgkgKiAJCSAgICJcdTAzMEFcdTAzMjUiLCAiXHUwMzAxXHUwMzI1Ii4KCSAqIHN0ZXAgMjogY2hlY2sgaWYgYW55IG9mIHRoZSBnZW5lcmF0ZWQgc3Vic3RyaW5ncyBtYXRjaGVzIHRoZSBwYXR0ZXJuLgoJICogSW50ZXJuYWwgbWV0aG9kLCBzdGF0dXMgaXMgYXNzdW1lZCB0byBiZSBzdWNjZXNzLCBjYWxsZXIgaGFzIHRvIGNoZWNrIAoJICogc3RhdHVzIGJlZm9yZSBjYWxsaW5nIHRoaXMgbWV0aG9kLgoJICogQHBhcmFtIHN0YXJ0IGZpcnN0IG9mZnNldCBvZiB0aGUgYWNjZW50cyB0byBzdGFydCBzZWFyY2hpbmcKCSAqIEBwYXJhbSBlbmQgc3RhcnQgb2YgdGhlIGxhc3QgYWNjZW50IHNldAoJICogQHJldHVybiBET05FIGlmIGEgbWF0Y2ggaXMgbm90IGZvdW5kLCBvdGhlcndpc2UgcmV0dXJuIHRoZSBzdGFydGluZwoJICogICAgICAgICBvZmZzZXQgb2YgdGhlIG1hdGNoLiBOb3RlIHRoaXMgc3RhcnQgaW5jbHVkZXMgYWxsIHByZWNlZGluZyAKCSAqIAkJICAgYWNjZW50cy4KCSAqLwoJcHJpdmF0ZSBpbnQgZG9OZXh0Q2Fub25pY2FsUHJlZml4TWF0Y2goaW50IHN0YXJ0LCBpbnQgZW5kKQoJewoJICAgIGlmICgoZ2V0RkNEKHRhcmdldFRleHQsIHN0YXJ0KSAmIExBU1RfQllURV9NQVNLXykgPT0gMCkgewoJICAgICAgICAvLyBkaWUuLi4gZmFpbGVkIGF0IGEgYmFzZSBjaGFyYWN0ZXIKCSAgICAgICAgcmV0dXJuIERPTkU7CgkgICAgfQoJCgkJc3RhcnQgPSB0YXJnZXRUZXh0LmdldEluZGV4KCk7IC8vIGluZGV4IGNoYW5nZWQgYnkgZmNkCgkgICAgaW50IG9mZnNldCA9IGdldE5leHRCYXNlT2Zmc2V0KHRhcmdldFRleHQsIHN0YXJ0KTsKCSAgICBzdGFydCA9IGdldFByZXZpb3VzQmFzZU9mZnNldChzdGFydCk7CgkKCSAgICBTdHJpbmdCdWZmZXIgYWNjZW50cyA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKCSAgICBTdHJpbmcgYWNjZW50c3RyID0gZ2V0U3RyaW5nKHRhcmdldFRleHQsIHN0YXJ0LCBvZmZzZXQgLSBzdGFydCk7CgkgICAgLy8gbm9ybWFsaXppbmcgdGhlIG9mZmVuc2l2ZSBzdHJpbmcKCSAgICBpZiAoTm9ybWFsaXplci5xdWlja0NoZWNrKGFjY2VudHN0ciwgTm9ybWFsaXplci5ORkQpIAoJICAgICAgICAJCQkJCQkJCQkJPT0gTm9ybWFsaXplci5OTykgewoJICAgICAgICBhY2NlbnRzdHIgPSBOb3JtYWxpemVyLmRlY29tcG9zZShhY2NlbnRzdHIsIGZhbHNlKTsKCSAgICB9CgkgICAgYWNjZW50cy5hcHBlbmQoYWNjZW50c3RyKTsKCSAgICAgICAgCgkgICAgaW50IGFjY2VudHNpbmRleFtdID0gbmV3IGludFtJTklUSUFMX0FSUkFZX1NJWkVfXTsgICAgICAKCSAgICBpbnQgYWNjZW50c2l6ZSA9IGdldFVuYmxvY2tlZEFjY2VudEluZGV4KGFjY2VudHMsIGFjY2VudHNpbmRleCk7CgkgICAgaW50IGNvdW50ID0gKDIgPDwgKGFjY2VudHNpemUgLSAxKSkgLSAyOyAgCgkgICAgd2hpbGUgKGNvdW50ID4gMCkgewoJICAgIAkvLyBjb3B5IHRoZSBiYXNlIGNoYXJhY3RlcnMKCSAgICAJbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5kZWxldGUoMCwgCgkgICAgCQkJCQkJCQltX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfLmxlbmd0aCgpKTsKCSAgICAJaW50IGsgPSAwOwoJICAgICAgICBmb3IgKDsgayA8IGFjY2VudHNpbmRleFswXTsgayArKykgewoJICAgICAgICAgICAgbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5hcHBlbmQoYWNjZW50cy5jaGFyQXQoaykpOwoJICAgICAgICB9CgkgICAgICAgIC8vIGZvcm1pbmcgYWxsIHBvc3NpYmxlIGNhbm9uaWNhbCByZWFycmFuZ2VtZW50IGJ5IGRyb3BwaW5nCgkgICAgICAgIC8vIHNldHMgb2YgYWNjZW50cwoJICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8PSBhY2NlbnRzaXplIC0gMTsgaSArKykgewoJICAgICAgICAgICAgaW50IG1hc2sgPSAxIDw8IChhY2NlbnRzaXplIC0gaSAtIDEpOwoJICAgICAgICAgICAgaWYgKChjb3VudCAmIG1hc2spICE9IDApIHsKCSAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gYWNjZW50c2luZGV4W2ldOyBqIDwgYWNjZW50c2luZGV4W2kgKyAxXTsgCgkgICAgICAgICAgICAgICAgCQkJCQkJCQkJCQkJCWogKyspIHsKCSAgICAgICAgICAgICAgICAgICAgbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5hcHBlbmQoYWNjZW50cy5jaGFyQXQoaikpOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgICAgICBTdHJpbmdCdWZmZXIgbWF0Y2ggPSBtZXJnZShtX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfLAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRUZXh0LCBvZmZzZXQsIGVuZCwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXyk7CgkgICAgICAgICAgICAKCSAgICAgICAgLy8gaWYgc3RhdHVzIGlzIGEgZmFpbHVyZSwgdWNvbF9zZXRUZXh0IGRvZXMgbm90aGluZy4KCSAgICAgICAgLy8gcnVuIHRoZSBjb2xsYXRvciBpdGVyYXRvciB0aHJvdWdoIHRoaXMgbWF0Y2gKCSAgICAgICAgbV91dGlsQ29sRUl0ZXJfLnNldFRleHQobWF0Y2gudG9TdHJpbmcoKSk7CgkgICAgICAgIGlmIChjaGVja0NvbGxhdGlvbk1hdGNoKG1fdXRpbENvbEVJdGVyXykpIHsKCSAgICAgICAgIAlyZXR1cm4gc3RhcnQ7CgkgICAgICAgIH0KCSAgICAgICAgY291bnQgLS07CgkgICAgfQoJICAgIHJldHVybiBET05FOwoJfQoKCS8qKgoJKiBHZXRzIHRoZSBvZmZzZXQgdG8gdGhlIHNhZmUgcG9pbnQgaW4gdGV4dCBiZWZvcmUgdGV4dG9mZnNldC4KCSogaWUuIG5vdCB0aGUgbWlkZGxlIG9mIGEgY29udHJhY3Rpb24sIHN3YXBwYWJsZSBjaGFyYWN0ZXJzIG9yIAoJKiBzdXBwbGVtZW50YXJ5IGNoYXJhY3RlcnMuCgkqIEBwYXJhbSBzdGFydCBvZmZzZXQgaW4gc3RyaW5nCgkqIEBwYXJhbSB0ZXh0b2Zmc2V0IG9mZnNldCBpbiBzdHJpbmcKCSogQHJldHVybiBvZmZzZXQgdG8gdGhlIHByZXZpb3VzIHNhZmUgY2hhcmFjdGVyCgkqLwoJcHJpdmF0ZSBmaW5hbCBpbnQgZ2V0UHJldmlvdXNTYWZlT2Zmc2V0KGludCBzdGFydCwgaW50IHRleHRvZmZzZXQpCgl7CgkgICAgaW50IHJlc3VsdCA9IHRleHRvZmZzZXQ7IC8vIGZpcnN0IGNvbnRyYWN0aW9uIGNoYXJhY3RlcgoJICAgIHRhcmdldFRleHQuc2V0SW5kZXgodGV4dG9mZnNldCk7CgkgICAgd2hpbGUgKHJlc3VsdCA+PSBzdGFydCAmJiBtX2NvbGxhdG9yXy5pc1Vuc2FmZSh0YXJnZXRUZXh0LnByZXZpb3VzKCkpKSB7CgkgICAgICAgIHJlc3VsdCA9IHRhcmdldFRleHQuZ2V0SW5kZXgoKTsKCSAgICB9CgkgICAgaWYgKHJlc3VsdCAhPSBzdGFydCkgewoJICAgICAgICAvLyB0aGUgZmlyc3QgY29udHJhY3Rpb24gY2hhcmFjdGVyIGlzIGNvbnNpZGVyIHVuc2FmZSBoZXJlCgkgICAgICAgIHJlc3VsdCA9IHRhcmdldFRleHQuZ2V0SW5kZXgoKTsgLy8gb3JpZ2luYWxseSByZXN1bHQgLS07CgkgICAgfQoJICAgIHJldHVybiByZXN1bHQ7IAoJfQoKCS8qKgoJICogVGFrZSB0aGUgcmVhcnJhbmdlZCBlbmQgYWNjZW50cyBhbmQgdHJpZXMgbWF0Y2hpbmcuIElmIG1hdGNoIGZhaWxlZCBhdAoJICogYSBzZXBlcmF0ZSBwcmVjZWRpbmcgc2V0IG9mIGFjY2VudHMgKHNlcGVyYXRlZCBmcm9tIHRoZSByZWFycmFuZ2VkIG9uIGJ5CgkgKiBhdCBsZWFzdCBhIGJhc2UgY2hhcmFjdGVyKSB0aGVuIHdlIHJlYXJyYW5nZSB0aGUgcHJlY2VkaW5nIGFjY2VudHMgYW5kIAoJICogdHJpZXMgbWF0Y2hpbmcgYWdhaW4uCgkgKiBXZSBhbGxvdyBza2lwcGluZyBvZiB0aGUgZW5kcyBvZiB0aGUgYWNjZW50IHNldCBpZiB0aGUgY2VzIGRvIG5vdCBtYXRjaC4gCgkgKiBIb3dldmVyIGlmIHRoZSBmYWlsdXJlIGlzIGZvdW5kIGJlZm9yZSB0aGUgYWNjZW50IHNldCwgaXQgZmFpbHMuCgkgKiBJbnRlcm5hbCBtZXRob2QsIHN0YXR1cyBhc3N1bWVkIHRvIGJlIHN1Y2Nlc3MsIGNhbGxlciBoYXMgdG8gY2hlY2sgCgkgKiBzdGF0dXMgYmVmb3JlIGNhbGxpbmcgdGhpcyBtZXRob2QuCgkgKiBAcGFyYW0gdGV4dG9mZnNldCBvZiB0aGUgc3RhcnQgb2YgdGhlIHJlYXJyYW5nZWQgYWNjZW50CgkgKiBAcmV0dXJuIERPTkUgaWYgYSBtYXRjaCBpcyBub3QgZm91bmQsIG90aGVyd2lzZSByZXR1cm4gdGhlIHN0YXJ0aW5nCgkgKiAgICAgICAgIG9mZnNldCBvZiB0aGUgbWF0Y2guIE5vdGUgdGhpcyBzdGFydCBpbmNsdWRlcyBhbGwgcHJlY2VkaW5nIAoJICogICAgICAgICBhY2NlbnRzLgoJICovCglwcml2YXRlIGludCBkb05leHRDYW5vbmljYWxTdWZmaXhNYXRjaChpbnQgdGV4dG9mZnNldCkKCXsKCSAgICBpbnQgc2FmZWxlbmd0aCA9IDA7CgkgICAgU3RyaW5nQnVmZmVyIHNhZmV0ZXh0OwoJCWludCBzYWZlb2Zmc2V0ID0gbV90ZXh0QmVnaW5PZmZzZXRfOyAKCQkKCSAgICBpZiAodGV4dG9mZnNldCAhPSBtX3RleHRCZWdpbk9mZnNldF8gCgkgICAgCSYmIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18ubGVuZ3RoKCkgPiAwCgkgICAgCSYmIG1fY29sbGF0b3JfLmlzVW5zYWZlKG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18uY2hhckF0KDApKSkgewoJICAgICAgICBzYWZlb2Zmc2V0ICAgICA9IGdldFByZXZpb3VzU2FmZU9mZnNldChtX3RleHRCZWdpbk9mZnNldF8sIAoJICAgICAgICAJCQkJCQkJCQkJdGV4dG9mZnNldCk7CgkgICAgICAgIHNhZmVsZW5ndGggICAgID0gdGV4dG9mZnNldCAtIHNhZmVvZmZzZXQ7CgkgICAgICAgIHNhZmV0ZXh0ICAgICAgID0gbWVyZ2UobnVsbCwgdGFyZ2V0VGV4dCwgc2FmZW9mZnNldCwgdGV4dG9mZnNldCwgCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXyk7CgkgICAgfQoJICAgIGVsc2UgewoJICAgICAgICBzYWZldGV4dCA9IG1fY2Fub25pY2FsU3VmZml4QWNjZW50c187CgkgICAgfQoJCgkgICAgLy8gaWYgc3RhdHVzIGlzIGEgZmFpbHVyZSwgdWNvbF9zZXRUZXh0IGRvZXMgbm90aGluZwoJICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBjb2xlaXRlciA9IG1fdXRpbENvbEVJdGVyXzsKCSAgICBjb2xlaXRlci5zZXRUZXh0KHNhZmV0ZXh0LnRvU3RyaW5nKCkpOwoJICAgIC8vIHN0YXR1cyBjaGVja2VkIGluIGxvb3AgYmVsb3cKCQoJICAgIGludCBjZWluZGV4ID0gbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyAtIDE7CgkgICAgYm9vbGVhbiBpc1NhZmUgPSB0cnVlOyAvLyBpbmRpY2F0aW9uIGZsYWcgZm9yIHBvc2l0aW9uIGluIHNhZmUgem9uZQoJICAgIAoJICAgIHdoaWxlIChjZWluZGV4ID49IDApIHsKCSAgICAgICAgaW50IHRleHRjZSA9IGNvbGVpdGVyLnByZXZpb3VzKCk7CgkgICAgICAgIGlmICh0ZXh0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewoJICAgICAgICAgICAgLy8gY2hlY2sgaWYgd2UgaGF2ZSBwYXNzZWQgdGhlIHNhZmUgYnVmZmVyCgkgICAgICAgICAgICBpZiAoY29sZWl0ZXIgPT0gbV9jb2xFSXRlcl8pIHsKCSAgICAgICAgICAgICAgICByZXR1cm4gRE9ORTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGNvbGVpdGVyID0gbV9jb2xFSXRlcl87CgkgICAgICAgICAgICBpZiAoc2FmZXRleHQgIT0gbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXykgewoJICAgICAgICAgICAgCXNhZmV0ZXh0LmRlbGV0ZSgwLCBzYWZldGV4dC5sZW5ndGgoKSk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBjb2xlaXRlci5zZXRFeGFjdE9mZnNldChzYWZlb2Zmc2V0KTsKCSAgICAgICAgICAgIC8vIHN0YXR1cyBjaGVja2VkIGF0IHRoZSBzdGFydCBvZiB0aGUgbG9vcAoJICAgICAgICAgICAgaXNTYWZlID0gZmFsc2U7CgkgICAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgfQoJICAgICAgICB0ZXh0Y2UgPSBnZXRDRSh0ZXh0Y2UpOwoJICAgICAgICBpZiAodGV4dGNlICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUgCgkgICAgICAgIAkmJiB0ZXh0Y2UgIT0gbV9wYXR0ZXJuXy5tX0NFX1tjZWluZGV4XSkgewoJICAgICAgICAgICAgLy8gZG8gdGhlIGJlZ2lubmluZyBzdHVmZgoJICAgICAgICAgICAgaW50IGZhaWxlZG9mZnNldCA9IGNvbGVpdGVyLmdldE9mZnNldCgpOwoJICAgICAgICAgICAgaWYgKGlzU2FmZSAmJiBmYWlsZWRvZmZzZXQgPj0gc2FmZWxlbmd0aCkgewoJICAgICAgICAgICAgICAgIC8vIGFsYXMuLi4gbm8gaG9wZS4gZmFpbGVkIGF0IHJlYXJyYW5nZWQgYWNjZW50IHNldAoJICAgICAgICAgICAgICAgIHJldHVybiBET05FOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgZWxzZSB7CgkgICAgICAgICAgICAgICAgaWYgKGlzU2FmZSkgewoJICAgICAgICAgICAgICAgICAgICBmYWlsZWRvZmZzZXQgKz0gc2FmZW9mZnNldDsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgCgkgICAgICAgICAgICAgICAgLy8gdHJ5IHJlYXJyYW5naW5nIHRoZSBmcm9udCBhY2NlbnRzCgkgICAgICAgICAgICAgICAgaW50IHJlc3VsdCA9IGRvTmV4dENhbm9uaWNhbFByZWZpeE1hdGNoKGZhaWxlZG9mZnNldCwgCgkgICAgICAgICAgICAgICAgCQkJCQkJCQkJCXRleHRvZmZzZXQpOwoJICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gRE9ORSkgewoJICAgICAgICAgICAgICAgICAgICAvLyBpZiBzdGF0dXMgaXMgYSBmYWlsdXJlLCB1Y29sX3NldE9mZnNldCBkb2VzIG5vdGhpbmcKCSAgICAgICAgICAgICAgICAgICAgbV9jb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQocmVzdWx0KTsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgICAgICBpZiAodGV4dGNlID09IG1fcGF0dGVybl8ubV9DRV9bY2VpbmRleF0pIHsKCSAgICAgICAgICAgIGNlaW5kZXggLS07CgkgICAgICAgIH0KCSAgICB9CgkgICAgLy8gc2V0IG9mZnNldCBoZXJlCgkgICAgaWYgKGlzU2FmZSkgewoJICAgICAgICBpbnQgcmVzdWx0ID0gY29sZWl0ZXIuZ2V0T2Zmc2V0KCk7CgkgICAgICAgIC8vIHNldHMgdGhlIHRleHQgaXRlcmF0b3Igd2l0aCB0aGUgY29ycmVjdCBleHBhbnNpb24gYW5kIG9mZnNldAoJICAgICAgICBpbnQgbGVmdG92ZXJjZXMgPSBjb2xlaXRlci5tX0NFQnVmZmVyT2Zmc2V0XzsKCSAgICAgICAgaWYgKHJlc3VsdCA+PSBzYWZlbGVuZ3RoKSB7IAoJICAgICAgICAgICAgcmVzdWx0ID0gdGV4dG9mZnNldDsKCSAgICAgICAgfQoJICAgICAgICBlbHNlIHsKCSAgICAgICAgICAgIHJlc3VsdCArPSBzYWZlb2Zmc2V0OwoJICAgICAgICB9CgkgICAgICAgIG1fY29sRUl0ZXJfLnNldEV4YWN0T2Zmc2V0KHJlc3VsdCk7CgkgICAgICAgIG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJPZmZzZXRfID0gbGVmdG92ZXJjZXM7CgkgICAgICAgIHJldHVybiByZXN1bHQ7CgkgICAgfQoJICAgIAoJICAgIHJldHVybiBjb2xlaXRlci5nZXRPZmZzZXQoKTsgICAgICAgICAgICAgIAoJfQoJCgkvKioKCSAqIFRyeWluZyBvdXQgdGhlIHN1YnN0cmluZyBhbmQgc2VlcyBpZiBpdCBjYW4gYmUgYSBjYW5vbmljYWwgbWF0Y2guCgkgKiBUaGlzIHdpbGwgdHJ5IG5vcm1hbGl6aW5nIHRoZSBlbmQgYWNjZW50cyBhbmQgYXJyYW5naW5nIHRoZW0gaW50byAKCSAqIGNhbm9uaWNhbCBlcXVpdmFsZW50cyBhbmQgY2hlY2sgdGhlaXIgY29ycmVzcG9uZGluZyBjZXMgd2l0aCB0aGUgcGF0dGVybiAKCSAqIGNlLgoJICogU3VmZml4IGFjY2VudHMgaW4gdGhlIHRleHQgd2lsbCBiZSBncm91cGVkIGFjY29yZGluZyB0byB0aGVpciBjb21iaW5pbmcgCgkgKiBjbGFzcyBhbmQgdGhlIGdyb3VwcyB3aWxsIGJlIG1peGVkIGFuZCBtYXRjaGVkIHRvIHRyeSBmaW5kIHRoZSBwZXJmZWN0IAoJICogbWF0Y2ggd2l0aCB0aGUgcGF0dGVybi4KCSAqIFNvIGZvciBpbnN0YW5jZSBsb29raW5nIGZvciAiXHUwMzAxIiBpbiAiXHUwMzBBXHUwMzAxXHUwMzI1IgoJICogc3RlcCAxOiBzcGxpdCAiXHUwMzBBXHUwMzAxIiBpbnRvIDYgb3RoZXIgdHlwZSBvZiBwb3RlbnRpYWwgYWNjZW50IAoJICogICAgICAgICBzdWJzdHJpbmdzCgkgKiAgICAgICAgICJcdTAzMEEiLCAiXHUwMzAxIiwgIlx1MDMyNSIsICJcdTAzMEFcdTAzMDEiLCAiXHUwMzBBXHUwMzI1IiwgCgkgKiAgICAgICAgICJcdTAzMDFcdTAzMjUiLgoJICogc3RlcCAyOiBjaGVjayBpZiBhbnkgb2YgdGhlIGdlbmVyYXRlZCBzdWJzdHJpbmdzIG1hdGNoZXMgdGhlIHBhdHRlcm4uCgkgKiBAcGFyYW0gdGV4dG9mZnNldCBlbmQgb2Zmc2V0IGluIHRoZSBjb2xsYXRpb24gZWxlbWVudCB0ZXh0IHRoYXQgZW5kcyB3aXRoIAoJICogICAgICAgICAgICAgICAgICAgdGhlIGFjY2VudHMgdG8gYmUgcmVhcnJhbmdlZAoJICogQHJldHVybiB0cnVlIGlmIHRoZSBtYXRjaCBpcyB2YWxpZCwgZmFsc2Ugb3RoZXJ3aXNlCgkgKi8KCXByaXZhdGUgYm9vbGVhbiBkb05leHRDYW5vbmljYWxNYXRjaChpbnQgdGV4dG9mZnNldCkKCXsKCQlpbnQgb2Zmc2V0ID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CgkJdGFyZ2V0VGV4dC5zZXRJbmRleCh0ZXh0b2Zmc2V0KTsKCQlpZiAoVVRGMTYuaXNUcmFpbFN1cnJvZ2F0ZSh0YXJnZXRUZXh0LnByZXZpb3VzKCkpIAoJCQkmJiB0YXJnZXRUZXh0LmdldEluZGV4KCkgPiBtX3RleHRCZWdpbk9mZnNldF8pIHsgCgkJCWlmICghVVRGMTYuaXNMZWFkU3Vycm9nYXRlKHRhcmdldFRleHQucHJldmlvdXMoKSkpIHsKCQkJCXRhcmdldFRleHQubmV4dCgpOwoJCQl9CgkJfQoJICAgIGlmICgoZ2V0RkNEKHRhcmdldFRleHQsIHRhcmdldFRleHQuZ2V0SW5kZXgoKSkgJiBMQVNUX0JZVEVfTUFTS18pID09IDApIHsKCSAgICAgICAgaWYgKG1fcGF0dGVybl8ubV9oYXNQcmVmaXhBY2NlbnRzXykgewoJICAgICAgICAgICAgb2Zmc2V0ID0gZG9OZXh0Q2Fub25pY2FsUHJlZml4TWF0Y2gob2Zmc2V0LCB0ZXh0b2Zmc2V0KTsKCSAgICAgICAgICAgIGlmIChvZmZzZXQgIT0gRE9ORSkgewoJICAgICAgICAgICAgICAgIG1fY29sRUl0ZXJfLnNldEV4YWN0T2Zmc2V0KG9mZnNldCk7CgkgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICAgICAgcmV0dXJuIGZhbHNlOwoJICAgIH0KCQoJICAgIGlmICghbV9wYXR0ZXJuXy5tX2hhc1N1ZmZpeEFjY2VudHNfKSB7CgkgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICB9CgkKCSAgICBTdHJpbmdCdWZmZXIgYWNjZW50cyA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKCSAgICAvLyBvZmZzZXQgdG8gdGhlIGxhc3QgYmFzZSBjaGFyYWN0ZXIgaW4gc3Vic3RyaW5nIHRvIHNlYXJjaAoJICAgIGludCBiYXNlb2Zmc2V0ID0gZ2V0UHJldmlvdXNCYXNlT2Zmc2V0KHRhcmdldFRleHQsIHRleHRvZmZzZXQpOwoJICAgIC8vIG5vcm1hbGl6aW5nIHRoZSBvZmZlbnNpdmUgc3RyaW5nCgkgICAgU3RyaW5nIGFjY2VudHN0ciA9IGdldFN0cmluZyh0YXJnZXRUZXh0LCBiYXNlb2Zmc2V0LCAKCSAgICAJCQkJCQkJIHRleHRvZmZzZXQgLSBiYXNlb2Zmc2V0KTsKCSAgICBpZiAoTm9ybWFsaXplci5xdWlja0NoZWNrKGFjY2VudHN0ciwgTm9ybWFsaXplci5ORkQpIAoJICAgICAgICAJCQkJCQkJCQkJPT0gTm9ybWFsaXplci5OTykgewoJICAgICAgICBhY2NlbnRzdHIgPSBOb3JtYWxpemVyLmRlY29tcG9zZShhY2NlbnRzdHIsIGZhbHNlKTsKCSAgICB9CgkgICAgYWNjZW50cy5hcHBlbmQoYWNjZW50c3RyKTsKCSAgICAvLyBzdGF0dXMgY2hlY2tlZCBpbiBsb29wIGJlbG93CgkgICAgICAgIAoJICAgIGludCBhY2NlbnRzaW5kZXhbXSA9IG5ldyBpbnRbSU5JVElBTF9BUlJBWV9TSVpFX107CgkgICAgaW50IHNpemUgPSBnZXRVbmJsb2NrZWRBY2NlbnRJbmRleChhY2NlbnRzLCBhY2NlbnRzaW5kZXgpOwoJCgkgICAgLy8gMiBwb3dlciBuIC0gMSBtaW51cyB0aGUgZnVsbCBzZXQgb2YgYWNjZW50cwoJICAgIGludCAgY291bnQgPSAoMiA8PCAoc2l6ZSAtIDEpKSAtIDI7ICAKCSAgICB3aGlsZSAoY291bnQgPiAwKSB7CiAgICAgICAgICAgIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18uZGVsZXRlKDAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5sZW5ndGgoKSk7CgkgICAgICAgIC8vIGNvcHkgdGhlIGJhc2UgY2hhcmFjdGVycwoJICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IGFjY2VudHNpbmRleFswXTsgayArKykgewoJICAgICAgICAgICAgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5hcHBlbmQoYWNjZW50cy5jaGFyQXQoaykpOwoJICAgICAgICB9CgkgICAgICAgIC8vIGZvcm1pbmcgYWxsIHBvc3NpYmxlIGNhbm9uaWNhbCByZWFycmFuZ2VtZW50IGJ5IGRyb3BwaW5nCgkgICAgICAgIC8vIHNldHMgb2YgYWNjZW50cwoJICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8PSBzaXplIC0gMTsgaSArKykgewoJICAgICAgICAgICAgaW50IG1hc2sgPSAxIDw8IChzaXplIC0gaSAtIDEpOwoJICAgICAgICAgICAgaWYgKChjb3VudCAmIG1hc2spICE9IDApIHsKCSAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gYWNjZW50c2luZGV4W2ldOyBqIDwgYWNjZW50c2luZGV4W2kgKyAxXTsgCgkgICAgICAgICAgICAgICAgCWogKyspIHsKCSAgICAgICAgICAgICAgICAgICAgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5hcHBlbmQoYWNjZW50cy5jaGFyQXQoaikpOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgICAgICBvZmZzZXQgPSBkb05leHRDYW5vbmljYWxTdWZmaXhNYXRjaChiYXNlb2Zmc2V0KTsKCSAgICAgICAgaWYgKG9mZnNldCAhPSBET05FKSB7CgkgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gbWF0Y2ggZm91bmQKCSAgICAgICAgfQoJICAgICAgICBjb3VudCAtLTsKCSAgICB9CgkgICAgcmV0dXJuIGZhbHNlOwoJfQoJCgkvKioKCSAqIEdldHMgdGhlIHByZXZpb3VzIGJhc2UgY2hhcmFjdGVyIG9mZnNldCBkZXBlbmRpbmcgb24gdGhlIHN0cmluZyBzZWFyY2ggCgkgKiBwYXR0ZXJuIGRhdGEKCSAqIEBwYXJhbSBzdHJzcmNoIHN0cmluZyBzZWFyY2ggZGF0YQoJICogQHBhcmFtIHRleHRvZmZzZXQgY3VycmVudCBvZmZzZXQsIGN1cnJlbnQgY2hhcmFjdGVyCgkgKiBAcmV0dXJuIHRoZSBvZmZzZXQgb2YgdGhlIG5leHQgY2hhcmFjdGVyIGFmdGVyIHRoaXMgYmFzZSBjaGFyYWN0ZXIgb3IgCgkgKiAJCQlpdHNlbGYgaWYgaXQgaXMgYSBjb21wb3NlZCBjaGFyYWN0ZXIgd2l0aCBhY2NlbnRzCgkgKi8KCXByaXZhdGUgZmluYWwgaW50IGdldFByZXZpb3VzQmFzZU9mZnNldChpbnQgdGV4dG9mZnNldCkKCXsKCSAgICBpZiAobV9wYXR0ZXJuXy5tX2hhc1ByZWZpeEFjY2VudHNfICYmIHRleHRvZmZzZXQgPiBtX3RleHRCZWdpbk9mZnNldF8pIHsKCSAgICAgICAgaW50IG9mZnNldCA9IHRleHRvZmZzZXQ7CgkgICAgICAgIGlmICgoZ2V0RkNEKHRhcmdldFRleHQsIG9mZnNldCkgPj4gU0VDT05EX0xBU1RfQllURV9TSElGVF8pICE9IDApIHsKCSAgICAgICAgICAgIHJldHVybiBnZXRQcmV2aW91c0Jhc2VPZmZzZXQodGFyZ2V0VGV4dCwgdGV4dG9mZnNldCk7CgkgICAgICAgIH0KCSAgICB9CgkgICAgcmV0dXJuIHRleHRvZmZzZXQ7Cgl9CgkKCS8qKgoJICogQ2hlY2tzIG1hdGNoIGZvciBjb250cmFjdGlvbi4gCgkgKiBJZiB0aGUgbWF0Y2ggZW5kcyB3aXRoIGEgcGFydGlhbCBjb250cmFjdGlvbiB3ZSBmYWlsLgoJICogSWYgdGhlIG1hdGNoIHN0YXJ0cyB0b28gZmFyIG9mZiAoYmVjYXVzZSBvZiBiYWNrd2FyZHMgaXRlcmF0aW9uKSB3ZSB0cnkgCgkgKiB0byBjaGlwIG9mZiB0aGUgZXh0cmEgY2hhcmFjdGVycy4KCSAqIFVzZXMgdGhlIHRlbXBvcmFyeSB1dGlsIGJ1ZmZlciBmb3IgcmV0dXJuIHZhbHVlcyBvZiB0aGUgbW9kaWZpZWQgc3RhcnQKCSAqIGFuZCBlbmQuCgkgKiBAcGFyYW0gc3RhcnQgb2Zmc2V0IG9mIHBvdGVudGlhbCBtYXRjaCwgdG8gYmUgbW9kaWZpZWQgaWYgbmVjZXNzYXJ5CgkgKiBAcGFyYW0gZW5kIG9mZnNldCBvZiBwb3RlbnRpYWwgbWF0Y2gsIHRvIGJlIG1vZGlmaWVkIGlmIG5lY2Vzc2FyeQoJICogQHJldHVybiB0cnVlIGlmIG1hdGNoIHBhc3NlcyB0aGUgY29udHJhY3Rpb24gdGVzdCwgZmFsc2Ugb3RoZXJ3aXNlLiAKCSAqLwoJcHJpdmF0ZSBib29sZWFuIGNoZWNrTmV4dENhbm9uaWNhbENvbnRyYWN0aW9uTWF0Y2goaW50IHN0YXJ0LCBpbnQgZW5kKSAKCXsKCSAgICAvLyBUaGlzIHBhcnQgY2hlY2tzIGlmIGVpdGhlciBlbmRzIG9mIHRoZSBtYXRjaCBjb250YWlucyBwb3RlbnRpYWwgCgkgICAgLy8gY29udHJhY3Rpb24uIElmIHNvIHdlJ2xsIGhhdmUgdG8gaXRlcmF0ZSB0aHJvdWdoIHRoZW0KCSAgICBjaGFyIHNjaGFyID0gMDsKCSAgICBjaGFyIGVjaGFyID0gMDsKCSAgICBpZiAoZW5kIDwgbV90ZXh0TGltaXRPZmZzZXRfKSB7CgkgICAgCXRhcmdldFRleHQuc2V0SW5kZXgoZW5kKTsKCSAgICAJZWNoYXIgPSB0YXJnZXRUZXh0LmN1cnJlbnQoKTsKCSAgICB9CgkgICAgaWYgKHN0YXJ0IDwgbV90ZXh0TGltaXRPZmZzZXRfKSB7CgkgICAgCXRhcmdldFRleHQuc2V0SW5kZXgoc3RhcnQgKyAxKTsKCSAgICAJc2NoYXIgPSB0YXJnZXRUZXh0LmN1cnJlbnQoKTsKCSAgICB9CgkgICAgaWYgKG1fY29sbGF0b3JfLmlzVW5zYWZlKGVjaGFyKSB8fCBtX2NvbGxhdG9yXy5pc1Vuc2FmZShzY2hhcikpIHsKCSAgICAgICAgaW50IGV4cGFuc2lvbiAgPSBtX2NvbEVJdGVyXy5tX0NFQnVmZmVyT2Zmc2V0XzsKCSAgICAgICAgYm9vbGVhbiBoYXNFeHBhbnNpb24gPSBleHBhbnNpb24gPiAwOwoJICAgICAgICBtX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldChzdGFydCk7CgkgICAgICAgIGludCB0ZW1wID0gc3RhcnQ7CgkgICAgICAgIHdoaWxlIChleHBhbnNpb24gPiAwKSB7CgkgICAgICAgICAgICAvLyBnZXR0aW5nIHJpZCBvZiB0aGUgcmVkdW5kYW50IGNlLCBjYXVzZWQgYnkgc2V0T2Zmc2V0LgoJICAgICAgICAgICAgLy8gc2luY2UgYmFja3dhcmQgY29udHJhY3Rpb24vZXhwYW5zaW9uIG1heSBoYXZlIGV4dHJhIGNlcyBpZiAKCSAgICAgICAgICAgIC8vIHdlIGFyZSBpbiB0aGUgbm9ybWFsaXphdGlvbiBidWZmZXIsIGhhc0FjY2VudHNCZWZvcmVNYXRjaCAKCSAgICAgICAgICAgIC8vIHdvdWxkIGhhdmUgdGFrZW4gY2FyZSBvZiBpdC4KCSAgICAgICAgICAgIC8vIEUuZy4gdGhlIGNoYXJhY3RlciBcdTAxRkEgd2lsbCBoYXZlIGFuIGV4cGFuc2lvbiBvZiAzLCBidXQgCgkgICAgICAgICAgICAvLyBpZiB3ZSBhcmUgb25seSBsb29raW5nIGZvciBhY3V0ZSBhbmQgcmluZyBcdTAzMEEgYW5kIFx1MDMwMSwgCgkgICAgICAgICAgICAvLyB3ZSdsbCBoYXZlIHRvIHNraXAgdGhlIGZpcnN0IGNlIGluIHRoZSBleHBhbnNpb24gYnVmZmVyLgoJICAgICAgICAgICAgbV9jb2xFSXRlcl8ubmV4dCgpOwoJICAgICAgICAgICAgaWYgKG1fY29sRUl0ZXJfLmdldE9mZnNldCgpICE9IHRlbXApIHsKCSAgICAgICAgICAgICAgICBzdGFydCA9IHRlbXA7CgkgICAgICAgICAgICAgICAgdGVtcCAgPSBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGV4cGFuc2lvbiAtLTsKCSAgICAgICAgfQoJCgkgICAgICAgIGludCBjb3VudCA9IDA7CgkgICAgICAgIHdoaWxlIChjb3VudCA8IG1fcGF0dGVybl8ubV9DRUxlbmd0aF8pIHsKCSAgICAgICAgICAgIGludCBjZSA9IGdldENFKG1fY29sRUl0ZXJfLm5leHQoKSk7CgkgICAgICAgICAgICAvLyBzdGF0dXMgY2hlY2tlZCBiZWxvdywgbm90ZSB0aGF0IGlmIHN0YXR1cyBpcyBhIGZhaWx1cmUKCSAgICAgICAgICAgIC8vIHVjb2xfbmV4dCByZXR1cm5zIFVDT0xfTlVMTE9SREVSCgkgICAgICAgICAgICBpZiAoY2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKGhhc0V4cGFuc2lvbiAmJiBjb3VudCA9PSAwIAoJICAgICAgICAgICAgCSYmIG1fY29sRUl0ZXJfLmdldE9mZnNldCgpICE9IHRlbXApIHsKCSAgICAgICAgICAgICAgICBzdGFydCA9IHRlbXA7CgkgICAgICAgICAgICAgICAgdGVtcCA9IG1fY29sRUl0ZXJfLmdldE9mZnNldCgpOwoJICAgICAgICAgICAgfQoJCgkgICAgICAgICAgICBpZiAoY291bnQgPT0gMCAmJiBjZSAhPSBtX3BhdHRlcm5fLm1fQ0VfWzBdKSB7CgkgICAgICAgICAgICAgICAgLy8gYWNjZW50cyBtYXkgaGF2ZSBleHRyYSBzdGFydGluZyBjZXMsIHRoaXMgb2NjdXJzIHdoZW4gYSAKCSAgICAgICAgICAgICAgICAvLyBwdXJlIGFjY2VudCBwYXR0ZXJuIGlzIG1hdGNoZWQgd2l0aG91dCByZWFycmFuZ2VtZW50CgkgICAgICAgICAgICAgICAgLy8gdGV4dCBcdTAzMjVcdTAzMDAgYW5kIGxvb2tpbmcgZm9yIFx1MDMwMAoJICAgICAgICAgICAgICAgIGludCBleHBlY3RlZCA9IG1fcGF0dGVybl8ubV9DRV9bMF07IAoJICAgICAgICAgICAgICAgIGlmICgoZ2V0RkNEKHRhcmdldFRleHQsIHN0YXJ0KSAmIExBU1RfQllURV9NQVNLXykgIT0gMCkgewoJICAgICAgICAgICAgICAgICAgICBjZSA9IGdldENFKG1fY29sRUl0ZXJfLm5leHQoKSk7CgkgICAgICAgICAgICAgICAgICAgIHdoaWxlIChjZSAhPSBleHBlY3RlZCAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGNlICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIgCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKSA8PSBlbmQpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIGNlID0gZ2V0Q0UobV9jb2xFSXRlcl8ubmV4dCgpKTsKCSAgICAgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGlmIChjZSAhPSBtX3BhdHRlcm5fLm1fQ0VfW2NvdW50XSkgewoJICAgICAgICAgICAgICAgIGVuZCArKzsKCSAgICAgICAgICAgICAgICBlbmQgPSBnZXROZXh0QmFzZU9mZnNldChlbmQpOyAgCgkgICAgICAgICAgICAgICAgbV91dGlsQnVmZmVyX1swXSA9IHN0YXJ0OwoJICAgICAgICAgICAgICAgIG1fdXRpbEJ1ZmZlcl9bMV0gPSBlbmQ7CgkgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgY291bnQgKys7CgkgICAgICAgIH0KCSAgICB9IAoJICAgIG1fdXRpbEJ1ZmZlcl9bMF0gPSBzdGFydDsKCSAgICBtX3V0aWxCdWZmZXJfWzFdID0gZW5kOwoJICAgIHJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogQ2hlY2tzIGFuZCBzZXRzIHRoZSBtYXRjaCBpbmZvcm1hdGlvbiBpZiBmb3VuZC4KCSAqIENoZWNrcyAKCSAqIDx1bD4KCSAqIDxsaT4gdGhlIHBvdGVudGlhbCBtYXRjaCBkb2VzIG5vdCByZXBlYXQgdGhlIHByZXZpb3VzIG1hdGNoCgkgKiA8bGk+IGJvdW5kYXJpZXMgYXJlIGNvcnJlY3QKCSAqIDxsaT4gcG90ZW50aWFsIG1hdGNoIGRvZXMgbm90IGVuZCBpbiB0aGUgbWlkZGxlIG9mIGEgY29udHJhY3Rpb24KCSAqIDxsaT4gaWRlbnRpY2FsIG1hdGNoZXMKCSAqIDwvdWw+CgkgKiBPdGhlcndpc2UgdGhlIG9mZnNldCB3aWxsIGJlIHNoaWZ0ZWQgdG8gdGhlIG5leHQgY2hhcmFjdGVyLgoJICogVGhlIHJlc3VsdCBtX21hdGNoSW5kZXhfIGFuZCBtX21hdGNoTGVuZ3RoXyB3aWxsIGJlIHNldCB0byB0aGUgdHJ1bmNhdGVkCgkgKiBtb3JlIGZpdHRpbmcgcmVzdWx0IHZhbHVlLgoJICogVXNlcyB0aGUgdGVtcG9yYXJ5IHV0aWxpdHkgYnVmZmVyIGZvciBzdG9yaW5nIHRoZSBtb2RpZmllZCB0ZXh0b2Zmc2V0LgoJICogQHBhcmFtIHRleHRvZmZzZXQgb2Zmc2V0IGluIHRoZSBjb2xsYXRpb24gZWxlbWVudCB0ZXh0LgoJICogQHJldHVybiB0cnVlIGlmIHRoZSBtYXRjaCBpcyB2YWxpZCwgZmFsc2Ugb3RoZXJ3aXNlCgkgKi8KCXByaXZhdGUgYm9vbGVhbiBjaGVja05leHRDYW5vbmljYWxNYXRjaChpbnQgdGV4dG9mZnNldCkKCXsKCSAgICAvLyB0byBlbnN1cmUgdGhhdCB0aGUgc3RhcnQgYW5kIGVuZHMgYXJlIG5vdCBjb21wb3NpdGUgY2hhcmFjdGVycwoJICAgIC8vIGlmIHdlIGhhdmUgYSBjYW5vbmljYWwgYWNjZW50IG1hdGNoCgkgICAgaWYgKChtX3BhdHRlcm5fLm1faGFzU3VmZml4QWNjZW50c18gCgkgICAgCQkmJiBtX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfLmxlbmd0aCgpICE9IDApIHx8IAoJICAgICAgICAobV9wYXR0ZXJuXy5tX2hhc1ByZWZpeEFjY2VudHNfIAoJICAgICAgICAJJiYgbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5sZW5ndGgoKSAhPSAwKSkgewoJICAgICAgICBtX21hdGNoZWRJbmRleF8gPSBnZXRQcmV2aW91c0Jhc2VPZmZzZXQobV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCkpOwoJICAgICAgICBtYXRjaExlbmd0aCA9IHRleHRvZmZzZXQgLSBtX21hdGNoZWRJbmRleF87CgkgICAgICAgIHJldHVybiB0cnVlOwoJICAgIH0KCQoJICAgIGludCBzdGFydCA9IG1fY29sRUl0ZXJfLmdldE9mZnNldCgpOwoJICAgIGlmICghY2hlY2tOZXh0Q2Fub25pY2FsQ29udHJhY3Rpb25NYXRjaChzdGFydCwgdGV4dG9mZnNldCkpIHsKCSAgICAJLy8gcmV0dXJuIHRoZSBtb2RpZmllZCB0ZXh0b2Zmc2V0CgkgICAgCW1fdXRpbEJ1ZmZlcl9bMF0gPSBtX3V0aWxCdWZmZXJfWzFdOyAKCSAgICAgICAgcmV0dXJuIGZhbHNlOwoJICAgIH0KCSAgICBzdGFydCA9IG1fdXRpbEJ1ZmZlcl9bMF07CgkgICAgdGV4dG9mZnNldCA9IG1fdXRpbEJ1ZmZlcl9bMV07CgkgICAgc3RhcnQgPSBnZXRQcmV2aW91c0Jhc2VPZmZzZXQoc3RhcnQpOwoJICAgIC8vIHRoaXMgdG90YWxseSBtYXRjaGVzLCBob3dldmVyIHdlIG5lZWQgdG8gY2hlY2sgaWYgaXQgaXMgcmVwZWF0aW5nCgkgICAgaWYgKGNoZWNrUmVwZWF0ZWRNYXRjaChzdGFydCwgdGV4dG9mZnNldCkgCgkgICAgCXx8ICFpc0JyZWFrVW5pdChzdGFydCwgdGV4dG9mZnNldCkgCgkgICAgCXx8ICFjaGVja0lkZW50aWNhbChzdGFydCwgdGV4dG9mZnNldCkpIHsKCSAgICAgICAgdGV4dG9mZnNldCArKzsKCSAgICAgICAgdGV4dG9mZnNldCA9IGdldE5leHRCYXNlT2Zmc2V0KHRhcmdldFRleHQsIHRleHRvZmZzZXQpOwoJICAgICAgICBtX3V0aWxCdWZmZXJfWzBdID0gdGV4dG9mZnNldDsKCSAgICAgICAgcmV0dXJuIGZhbHNlOwoJICAgIH0KCSAgICAKCSAgICBtX21hdGNoZWRJbmRleF8gID0gc3RhcnQ7CgkgICAgbWF0Y2hMZW5ndGggPSB0ZXh0b2Zmc2V0IC0gc3RhcnQ7CgkgICAgcmV0dXJuIHRydWU7Cgl9CgkKCS8qKgoJICogU2hpZnRpbmcgdGhlIGNvbGxhdGlvbiBlbGVtZW50IGl0ZXJhdG9yIHBvc2l0aW9uIGZvcndhcmQgdG8gcHJlcGFyZSBmb3IKCSAqIGEgcHJlY2VkaW5nIG1hdGNoLiBJZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGlzIGEgdW5zYWZlIGNoYXJhY3Rlciwgd2UnbGwgCgkgKiBvbmx5IHNoaWZ0IGJ5IDEgdG8gY2FwdHVyZSBjb250cmFjdGlvbnMsIG5vcm1hbGl6YXRpb24gZXRjLgoJICogQHBhcmFtIHRleHRvZmZzZXQgc3RhcnQgdGV4dCBwb3NpdGlvbiB0byBkbyBzZWFyY2gKCSAqIEBwYXJhbSBjZSB0aGUgdGV4dCBjZSB3aGljaCBmYWlsZWQgdGhlIG1hdGNoLgoJICogQHBhcmFtIHBhdHRlcm5jZWluZGV4IGluZGV4IG9mIHRoZSBjZSB3aXRoaW4gdGhlIHBhdHRlcm4gY2UgYnVmZmVyIHdoaWNoCgkgKiAgICAgICAgZmFpbGVkIHRoZSBtYXRjaAoJICogQHJldHVybiBmaW5hbCBvZmZzZXQKCSAqLwoJcHJpdmF0ZSBpbnQgcmV2ZXJzZVNoaWZ0KGludCB0ZXh0b2Zmc2V0LCBpbnQgY2UsIGludCBwYXR0ZXJuY2VpbmRleCkKCXsgICAgICAgICAKCSAgICBpZiAoaXNPdmVybGFwcGluZygpKSB7CgkgICAgICAgIGlmICh0ZXh0b2Zmc2V0ICE9IG1fdGV4dExpbWl0T2Zmc2V0XykgewoJICAgICAgICAgICAgdGV4dG9mZnNldCAtLTsKCSAgICAgICAgfQoJICAgICAgICBlbHNlIHsKCSAgICAgICAgICAgIHRleHRvZmZzZXQgLT0gbV9wYXR0ZXJuXy5tX2RlZmF1bHRTaGlmdFNpemVfOwoJICAgICAgICB9CgkgICAgfQoJICAgIGVsc2UgewoJICAgICAgICBpZiAoY2UgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewoJICAgICAgICAgICAgaW50IHNoaWZ0ID0gbV9wYXR0ZXJuXy5tX2JhY2tTaGlmdF9baGFzaChjZSldOwoJICAgICAgICAgICAgCgkgICAgICAgICAgICAvLyB0aGlzIGlzIHRvIGFkanVzdCBmb3IgY2hhcmFjdGVycyBpbiB0aGUgbWlkZGxlIG9mIHRoZSBzdWJzdHJpbmcgCgkgICAgICAgICAgICAvLyBmb3IgbWF0Y2hpbmcgdGhhdCBmYWlsZWQuCgkgICAgICAgICAgICBpbnQgYWRqdXN0ID0gcGF0dGVybmNlaW5kZXg7CgkgICAgICAgICAgICBpZiAoYWRqdXN0ID4gMSAmJiBzaGlmdCA+IGFkanVzdCkgewoJICAgICAgICAgICAgICAgIHNoaWZ0IC09IGFkanVzdCAtIDE7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICB0ZXh0b2Zmc2V0IC09IHNoaWZ0OwoJICAgICAgICB9CgkgICAgICAgIGVsc2UgewoJICAgICAgICAgICAgdGV4dG9mZnNldCAtPSBtX3BhdHRlcm5fLm1fZGVmYXVsdFNoaWZ0U2l6ZV87CgkgICAgICAgIH0KCSAgICB9ICAgIAogICAgICAgIAoJICAgIHRleHRvZmZzZXQgPSBnZXRQcmV2aW91c0Jhc2VPZmZzZXQodGV4dG9mZnNldCk7CgkgICAgcmV0dXJuIHRleHRvZmZzZXQ7Cgl9CgoJLyoqCgkgKiBDaGVja3MgbWF0Y2ggZm9yIGNvbnRyYWN0aW9uLiAKCSAqIElmIHRoZSBtYXRjaCBzdGFydHMgd2l0aCBhIHBhcnRpYWwgY29udHJhY3Rpb24gd2UgZmFpbC4KCSAqIFVzZXMgdGhlIHRlbXBvcmFyeSB1dGlsaXR5IGJ1ZmZlciB0byByZXR1cm4gdGhlIG1vZGlmaWVkIHN0YXJ0IGFuZCBlbmQuCgkgKiBAcGFyYW0gc3RhcnQgb2Zmc2V0IG9mIHBvdGVudGlhbCBtYXRjaCwgdG8gYmUgbW9kaWZpZWQgaWYgbmVjZXNzYXJ5CgkgKiBAcGFyYW0gZW5kIG9mZnNldCBvZiBwb3RlbnRpYWwgbWF0Y2gsIHRvIGJlIG1vZGlmaWVkIGlmIG5lY2Vzc2FyeQoJICogQHJldHVybiB0cnVlIGlmIG1hdGNoIHBhc3NlcyB0aGUgY29udHJhY3Rpb24gdGVzdCwgZmFsc2Ugb3RoZXJ3aXNlLgoJICovCglwcml2YXRlIGJvb2xlYW4gY2hlY2tQcmV2aW91c0V4YWN0Q29udHJhY3Rpb25NYXRjaChpbnQgc3RhcnQsIGludCBlbmQpIAoJewoJICAgIC8vIFRoaXMgcGFydCBjaGVja3MgaWYgZWl0aGVyIGVuZHMgb2YgdGhlIG1hdGNoIGNvbnRhaW5zIHBvdGVudGlhbCAKCSAgICAvLyBjb250cmFjdGlvbi4gSWYgc28gd2UnbGwgaGF2ZSB0byBpdGVyYXRlIHRocm91Z2ggdGhlbQoJICAgIGNoYXIgZWNoYXIgPSAwOwoJICAgIGlmIChlbmQgPCBtX3RleHRMaW1pdE9mZnNldF8pIHsKCSAgICAJdGFyZ2V0VGV4dC5zZXRJbmRleChlbmQpOwoJICAgIAllY2hhciA9IHRhcmdldFRleHQuY3VycmVudCgpOwoJICAgIH0KCSAgICBjaGFyIHNjaGFyID0gMDsKCSAgICBpZiAoc3RhcnQgKyAxIDwgbV90ZXh0TGltaXRPZmZzZXRfKSB7CgkgICAgCXRhcmdldFRleHQuc2V0SW5kZXgoc3RhcnQgKyAxKTsKCSAgICAJc2NoYXIgPSB0YXJnZXRUZXh0LmN1cnJlbnQoKTsKCSAgICB9CgkgICAgaWYgKG1fY29sbGF0b3JfLmlzVW5zYWZlKGVjaGFyKSB8fCBtX2NvbGxhdG9yXy5pc1Vuc2FmZShzY2hhcikpIHsKCSAgICAJLy8gZXhwYW5zaW9uIHN1ZmZpeCwgd2hhdCdzIGxlZnQgdG8gaXRlcmF0ZQoJICAgICAgICBpbnQgZXhwYW5zaW9uID0gbV9jb2xFSXRlcl8ubV9DRUJ1ZmZlclNpemVfIAoJICAgICAgICAJCQkJCQkJCS0gbV9jb2xFSXRlcl8ubV9DRUJ1ZmZlck9mZnNldF87CgkgICAgICAgIGJvb2xlYW4gaGFzRXhwYW5zaW9uID0gZXhwYW5zaW9uID4gMDsKCSAgICAgICAgbV9jb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQoZW5kKTsKCSAgICAgICAgaW50IHRlbXAgPSBlbmQ7CgkgICAgICAgIHdoaWxlIChleHBhbnNpb24gPiAwKSB7CgkgICAgICAgICAgICAvLyBnZXR0aW5nIHJpZCBvZiB0aGUgcmVkdW5kYW50IGNlCgkgICAgICAgICAgICAvLyBzaW5jZSBmb3J3YXJkIGNvbnRyYWN0aW9uL2V4cGFuc2lvbiBtYXkgaGF2ZSBleHRyYSBjZXMKCSAgICAgICAgICAgIC8vIGlmIHdlIGFyZSBpbiB0aGUgbm9ybWFsaXphdGlvbiBidWZmZXIsIGhhc0FjY2VudHNCZWZvcmVNYXRjaAoJICAgICAgICAgICAgLy8gd291bGQgaGF2ZSB0YWtlbiBjYXJlIG9mIGl0LgoJICAgICAgICAgICAgLy8gRS5nLiB0aGUgY2hhcmFjdGVyIFx1MDFGQSB3aWxsIGhhdmUgYW4gZXhwYW5zaW9uIG9mIDMsIGJ1dCBpZgoJICAgICAgICAgICAgLy8gd2UgYXJlIG9ubHkgbG9va2luZyBmb3IgQSByaW5nIEFcdTAzMEEsIHdlJ2xsIGhhdmUgdG8gc2tpcCB0aGUgCgkgICAgICAgICAgICAvLyBsYXN0IGNlIGluIHRoZSBleHBhbnNpb24gYnVmZmVyCgkgICAgICAgICAgICBtX2NvbEVJdGVyXy5wcmV2aW91cygpOwoJICAgICAgICAgICAgaWYgKG1fY29sRUl0ZXJfLmdldE9mZnNldCgpICE9IHRlbXApIHsKCSAgICAgICAgICAgICAgICBlbmQgPSB0ZW1wOwoJICAgICAgICAgICAgICAgIHRlbXAgPSBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGV4cGFuc2lvbiAtLTsKCSAgICAgICAgfQoJCgkgICAgICAgIGludCBjb3VudCA9IG1fcGF0dGVybl8ubV9DRUxlbmd0aF87CgkgICAgICAgIHdoaWxlIChjb3VudCA+IDApIHsKCSAgICAgICAgICAgIGludCBjZSA9IGdldENFKG1fY29sRUl0ZXJfLnByZXZpb3VzKCkpOwoJICAgICAgICAgICAgLy8gc3RhdHVzIGNoZWNrZWQgYmVsb3csIG5vdGUgdGhhdCBpZiBzdGF0dXMgaXMgYSBmYWlsdXJlCgkgICAgICAgICAgICAvLyB1Y29sX3ByZXZpb3VzIHJldHVybnMgVUNPTF9OVUxMT1JERVIKCSAgICAgICAgICAgIGlmIChjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CgkgICAgICAgICAgICAgICAgY29udGludWU7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAoaGFzRXhwYW5zaW9uICYmIGNvdW50ID09IDAgCgkgICAgICAgICAgICAJJiYgbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCkgIT0gdGVtcCkgewoJICAgICAgICAgICAgICAgIGVuZCA9IHRlbXA7CgkgICAgICAgICAgICAgICAgdGVtcCA9IG1fY29sRUl0ZXJfLmdldE9mZnNldCgpOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKGNlICE9IG1fcGF0dGVybl8ubV9DRV9bY291bnQgLSAxXSkgewoJICAgICAgICAgICAgICAgIHN0YXJ0IC0tOwoJICAgICAgICAgICAgICAgIHN0YXJ0ID0gZ2V0UHJldmlvdXNCYXNlT2Zmc2V0KHRhcmdldFRleHQsIHN0YXJ0KTsKCSAgICAgICAgICAgICAgICBtX3V0aWxCdWZmZXJfWzBdID0gc3RhcnQ7CgkgICAgICAgICAgICAgICAgbV91dGlsQnVmZmVyX1sxXSA9IGVuZDsKCSAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBjb3VudCAtLTsKCSAgICAgICAgfQoJICAgIH0gCgkgICAgbV91dGlsQnVmZmVyX1swXSA9IHN0YXJ0OwoJICAgIG1fdXRpbEJ1ZmZlcl9bMV0gPSBlbmQ7CgkgICAgcmV0dXJuIHRydWU7Cgl9CgkKCS8qKgoJICogQ2hlY2tzIGFuZCBzZXRzIHRoZSBtYXRjaCBpbmZvcm1hdGlvbiBpZiBmb3VuZC4KCSAqIENoZWNrcyAKCSAqIDx1bD4KCSAqIDxsaT4gdGhlIGN1cnJlbnQgbWF0Y2ggZG9lcyBub3QgcmVwZWF0IHRoZSBsYXN0IG1hdGNoCgkgKiA8bGk+IGJvdW5kYXJpZXMgYXJlIGNvcnJlY3QKCSAqIDxsaT4gZXhhY3QgbWF0Y2hlcyBoYXMgbm8gZXh0cmEgYWNjZW50cwoJICogPGxpPiBpZGVudGljYWwgbWF0Y2hlcwoJICogPC91bD4KCSAqIE90aGVyd2lzZSB0aGUgb2Zmc2V0IHdpbGwgYmUgc2hpZnRlZCB0byB0aGUgcHJlY2VkaW5nIGNoYXJhY3Rlci4KCSAqIFVzZXMgdGhlIHRlbXBvcmFyeSB1dGlsaXR5IGJ1ZmZlciB0byBzdG9yZSB0aGUgbW9kaWZpZWQgdGV4dG9mZnNldC4KCSAqIEBwYXJhbSB0ZXh0b2Zmc2V0IG9mZnNldCBpbiB0aGUgY29sbGF0aW9uIGVsZW1lbnQgdGV4dC4gdGhlIHJldHVybmVkIHZhbHVlCgkgKiAgICAgICAgd2lsbCBiZSB0aGUgdHJ1bmNhdGVkIHN0YXJ0IG9mZnNldCBvZiB0aGUgbWF0Y2ggb3IgdGhlIG5ldyBzdGFydCAKCSAqICAgICAgICBzZWFyY2ggb2Zmc2V0LgoJICogQHJldHVybiB0cnVlIGlmIHRoZSBtYXRjaCBpcyB2YWxpZCwgZmFsc2Ugb3RoZXJ3aXNlCgkgKi8KCXByaXZhdGUgZmluYWwgYm9vbGVhbiBjaGVja1ByZXZpb3VzRXhhY3RNYXRjaChpbnQgdGV4dG9mZnNldCkKCXsKCSAgICAvLyB0byBlbnN1cmUgdGhhdCB0aGUgc3RhcnQgYW5kIGVuZHMgYXJlIG5vdCBjb21wb3NpdGUgY2hhcmFjdGVycwoJICAgIGludCBlbmQgPSBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKTsgICAgICAgIAoJICAgIGlmICghY2hlY2tQcmV2aW91c0V4YWN0Q29udHJhY3Rpb25NYXRjaCh0ZXh0b2Zmc2V0LCBlbmQpKSB7CgkgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICB9CgkgICAgdGV4dG9mZnNldCA9IG1fdXRpbEJ1ZmZlcl9bMF07CgkgICAgZW5kID0gbV91dGlsQnVmZmVyX1sxXTsKCSAgICAgICAgCgkgICAgLy8gdGhpcyB0b3RhbGx5IG1hdGNoZXMsIGhvd2V2ZXIgd2UgbmVlZCB0byBjaGVjayBpZiBpdCBpcyByZXBlYXRpbmcKCSAgICAvLyB0aGUgb2xkIG1hdGNoCgkgICAgaWYgKGNoZWNrUmVwZWF0ZWRNYXRjaCh0ZXh0b2Zmc2V0LCBlbmQpIAoJICAgIAl8fCAhaXNCcmVha1VuaXQodGV4dG9mZnNldCwgZW5kKSAKCSAgICAJfHwgaGFzQWNjZW50c0JlZm9yZU1hdGNoKHRleHRvZmZzZXQsIGVuZCkgCgkgICAgCXx8ICFjaGVja0lkZW50aWNhbCh0ZXh0b2Zmc2V0LCBlbmQpIAoJICAgIAl8fCBoYXNBY2NlbnRzQWZ0ZXJNYXRjaCh0ZXh0b2Zmc2V0LCBlbmQpKSB7CgkgICAgICAgIHRleHRvZmZzZXQgLS07CgkgICAgICAgIHRleHRvZmZzZXQgPSBnZXRQcmV2aW91c0Jhc2VPZmZzZXQodGFyZ2V0VGV4dCwgdGV4dG9mZnNldCk7CgkgICAgICAgIG1fdXRpbEJ1ZmZlcl9bMF0gPSB0ZXh0b2Zmc2V0OwoJICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgfQoJICAgIG1fbWF0Y2hlZEluZGV4XyA9IHRleHRvZmZzZXQ7CgkgICAgbWF0Y2hMZW5ndGggPSBlbmQgLSB0ZXh0b2Zmc2V0OwoJICAgIHJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogUmVhcnJhbmdlcyB0aGUgZW5kIGFjY2VudHMgdG8gdHJ5IG1hdGNoaW5nLgoJICogU3VmZml4IGFjY2VudHMgaW4gdGhlIHRleHQgd2lsbCBiZSBncm91cGVkIGFjY29yZGluZyB0byB0aGVpciBjb21iaW5pbmcgCgkgKiBjbGFzcyBhbmQgdGhlIGdyb3VwcyB3aWxsIGJlIG1peGVkIGFuZCBtYXRjaGVkIHRvIHRyeSBmaW5kIHRoZSBwZXJmZWN0IAoJICogbWF0Y2ggd2l0aCB0aGUgcGF0dGVybi4KCSAqIFNvIGZvciBpbnN0YW5jZSBsb29raW5nIGZvciAiXHUwMzAxIiBpbiAiXHUwMzBBXHUwMzAxXHUwMzI1IgoJICogc3RlcCAxOiBzcGxpdCAiXHUwMzBBXHUwMzAxIiBpbnRvIDYgb3RoZXIgdHlwZSBvZiBwb3RlbnRpYWwgYWNjZW50IAoJICogCQkJc3Vic3RyaW5ncwoJICogICAgICAgICAiXHUwMzBBIiwgIlx1MDMwMSIsICJcdTAzMjUiLCAiXHUwMzBBXHUwMzAxIiwgIlx1MDMwQVx1MDMyNSIsIAoJICogICAgICAgICAiXHUwMzAxXHUwMzI1Ii4KCSAqIHN0ZXAgMjogY2hlY2sgaWYgYW55IG9mIHRoZSBnZW5lcmF0ZWQgc3Vic3RyaW5ncyBtYXRjaGVzIHRoZSBwYXR0ZXJuLgoJICogQHBhcmFtIHN0YXJ0IG9mZnNldCBvZiB0aGUgZmlyc3QgYmFzZSBjaGFyYWN0ZXIKCSAqIEBwYXJhbSBlbmQgc3RhcnQgb2YgdGhlIGxhc3QgYWNjZW50IHNldAoJICogQHJldHVybiBET05FIGlmIGEgbWF0Y2ggaXMgbm90IGZvdW5kLCBvdGhlcndpc2UgcmV0dXJuIHRoZSBlbmRpbmcKCSAqICAgICAgICAgb2Zmc2V0IG9mIHRoZSBtYXRjaC4gTm90ZSB0aGlzIHN0YXJ0IGluY2x1ZGVzIGFsbCBmb2xsb3dpbmcgCgkgKiAgICAgICAgIGFjY2VudHMuCgkgKi8KCXByaXZhdGUgaW50IGRvUHJldmlvdXNDYW5vbmljYWxTdWZmaXhNYXRjaChpbnQgc3RhcnQsIGludCBlbmQpCgl7CgkgICAgdGFyZ2V0VGV4dC5zZXRJbmRleChlbmQpOwoJCWlmIChVVEYxNi5pc1RyYWlsU3Vycm9nYXRlKHRhcmdldFRleHQucHJldmlvdXMoKSkgCgkJCSYmIHRhcmdldFRleHQuZ2V0SW5kZXgoKSA+IG1fdGV4dEJlZ2luT2Zmc2V0XykgewoJCQlpZiAoIVVURjE2LmlzTGVhZFN1cnJvZ2F0ZSh0YXJnZXRUZXh0LnByZXZpb3VzKCkpKSB7CgkJCQl0YXJnZXRUZXh0Lm5leHQoKTsKCQkJfSAKCQl9CgkgICAgaWYgKChnZXRGQ0QodGFyZ2V0VGV4dCwgdGFyZ2V0VGV4dC5nZXRJbmRleCgpKSAmIExBU1RfQllURV9NQVNLXykgPT0gMCkgewoJICAgICAgICAvLyBkaWUuLi4gZmFpbGVkIGF0IGEgYmFzZSBjaGFyYWN0ZXIKCSAgICAgICAgcmV0dXJuIERPTkU7CgkgICAgfQoJICAgIGVuZCA9IGdldE5leHRCYXNlT2Zmc2V0KHRhcmdldFRleHQsIGVuZCk7CgkKCSAgICBTdHJpbmdCdWZmZXIgYWNjZW50cyA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKCSAgICBpbnQgb2Zmc2V0ID0gZ2V0UHJldmlvdXNCYXNlT2Zmc2V0KHRhcmdldFRleHQsIGVuZCk7CgkgICAgLy8gbm9ybWFsaXppbmcgdGhlIG9mZmVuc2l2ZSBzdHJpbmcKCSAgICBTdHJpbmcgYWNjZW50c3RyID0gZ2V0U3RyaW5nKHRhcmdldFRleHQsIG9mZnNldCwgZW5kIC0gb2Zmc2V0KTsKCSAgICBpZiAoTm9ybWFsaXplci5xdWlja0NoZWNrKGFjY2VudHN0ciwgTm9ybWFsaXplci5ORkQpIAoJICAgICAgICAJCQkJCQkJCQkJPT0gTm9ybWFsaXplci5OTykgewoJICAgICAgICBhY2NlbnRzdHIgPSBOb3JtYWxpemVyLmRlY29tcG9zZShhY2NlbnRzdHIsIGZhbHNlKTsKCSAgICB9CgkgICAgYWNjZW50cy5hcHBlbmQoYWNjZW50c3RyKTsgICAgCgkgICAgICAgIAoJICAgIGludCBhY2NlbnRzaW5kZXhbXSA9IG5ldyBpbnRbSU5JVElBTF9BUlJBWV9TSVpFX107ICAgICAgCgkgICAgaW50IGFjY2VudHNpemUgPSBnZXRVbmJsb2NrZWRBY2NlbnRJbmRleChhY2NlbnRzLCBhY2NlbnRzaW5kZXgpOwoJICAgIGludCBjb3VudCA9ICgyIDw8IChhY2NlbnRzaXplIC0gMSkpIC0gMjsgIAoJICAgIHdoaWxlIChjb3VudCA+IDApIHsKICAgICAgICAgICAgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5kZWxldGUoMCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfLmxlbmd0aCgpKTsKCSAgICAgICAgLy8gY29weSB0aGUgYmFzZSBjaGFyYWN0ZXJzCgkgICAgICAgIGZvciAoaW50IGsgPSAwOyBrIDwgYWNjZW50c2luZGV4WzBdOyBrICsrKSB7CgkgICAgICAgICAgICAgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5hcHBlbmQoYWNjZW50cy5jaGFyQXQoaykpOwoJICAgICAgICB9CgkgICAgICAgIC8vIGZvcm1pbmcgYWxsIHBvc3NpYmxlIGNhbm9uaWNhbCByZWFycmFuZ2VtZW50IGJ5IGRyb3BwaW5nCgkgICAgICAgIC8vIHNldHMgb2YgYWNjZW50cwoJICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8PSBhY2NlbnRzaXplIC0gMTsgaSArKykgewoJICAgICAgICAgICAgaW50IG1hc2sgPSAxIDw8IChhY2NlbnRzaXplIC0gaSAtIDEpOwoJICAgICAgICAgICAgaWYgKChjb3VudCAmIG1hc2spICE9IDApIHsKCSAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gYWNjZW50c2luZGV4W2ldOyBqIDwgYWNjZW50c2luZGV4W2kgKyAxXTsgCgkgICAgICAgICAgICAgICAgCQkJCQkJCQkJCQkJCWogKyspIHsKCSAgICAgICAgICAgICAgICAgICAgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5hcHBlbmQoYWNjZW50cy5jaGFyQXQoaikpOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgICAgICBTdHJpbmdCdWZmZXIgbWF0Y2ggPSBtZXJnZShtX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfLCB0YXJnZXRUZXh0LAoJICAgICAgICAJCQkJCQkJc3RhcnQsIG9mZnNldCwgCgkgICAgICAgIAkJCQkJCQltX2Nhbm9uaWNhbFN1ZmZpeEFjY2VudHNfKTsKCSAgICAgICAgLy8gcnVuIHRoZSBjb2xsYXRvciBpdGVyYXRvciB0aHJvdWdoIHRoaXMgbWF0Y2gKCSAgICAgICAgLy8gaWYgc3RhdHVzIGlzIGEgZmFpbHVyZSB1Y29sX3NldFRleHQgZG9lcyBub3RoaW5nCgkgICAgICAgIG1fdXRpbENvbEVJdGVyXy5zZXRUZXh0KG1hdGNoLnRvU3RyaW5nKCkpOwoJICAgICAgICBpZiAoY2hlY2tDb2xsYXRpb25NYXRjaChtX3V0aWxDb2xFSXRlcl8pKSB7CgkgICAgICAgICAgICByZXR1cm4gZW5kOwoJICAgICAgICB9CgkgICAgICAgIGNvdW50IC0tOwoJICAgIH0KCSAgICByZXR1cm4gRE9ORTsKCX0KCQoJLyoqCgkgKiBUYWtlIHRoZSByZWFycmFuZ2VkIHN0YXJ0IGFjY2VudHMgYW5kIHRyaWVzIG1hdGNoaW5nLiBJZiBtYXRjaCBmYWlsZWQgYXQKCSAqIGEgc2VwZXJhdGUgZm9sbG93aW5nIHNldCBvZiBhY2NlbnRzIChzZXBlcmF0ZWQgZnJvbSB0aGUgcmVhcnJhbmdlZCBvbiBieQoJICogYXQgbGVhc3QgYSBiYXNlIGNoYXJhY3RlcikgdGhlbiB3ZSByZWFycmFuZ2UgdGhlIHByZWNlZGluZyBhY2NlbnRzIGFuZCAKCSAqIHRyaWVzIG1hdGNoaW5nIGFnYWluLgoJICogV2UgYWxsb3cgc2tpcHBpbmcgb2YgdGhlIGVuZHMgb2YgdGhlIGFjY2VudCBzZXQgaWYgdGhlIGNlcyBkbyBub3QgbWF0Y2guIAoJICogSG93ZXZlciBpZiB0aGUgZmFpbHVyZSBpcyBmb3VuZCBiZWZvcmUgdGhlIGFjY2VudCBzZXQsIGl0IGZhaWxzLgoJICogSW50ZXJuYWwgbWV0aG9kLCBzdGF0dXMgYXNzdW1lZCB0byBiZSBzdWNjZXNzLCBjYWxsZXIgaGFzIHRvIGNoZWNrIAoJICogc3RhdHVzIGJlZm9yZSBjYWxsaW5nIHRoaXMgbWV0aG9kLgoJICogQHBhcmFtIHRleHRvZmZzZXQgb2YgdGhlIGVuZHMgb2YgdGhlIHJlYXJyYW5nZWQgYWNjZW50CgkgKiBAcmV0dXJuIERPTkUgaWYgYSBtYXRjaCBpcyBub3QgZm91bmQsIG90aGVyd2lzZSByZXR1cm4gdGhlIGVuZGluZyBvZmZzZXQgCgkgKiAJCQlvZiB0aGUgbWF0Y2guIE5vdGUgdGhpcyBzdGFydCBpbmNsdWRlcyBhbGwgZm9sbG93aW5nIGFjY2VudHMuCgkgKi8KCXByaXZhdGUgaW50IGRvUHJldmlvdXNDYW5vbmljYWxQcmVmaXhNYXRjaChpbnQgdGV4dG9mZnNldCkKCXsKCSAgICBpbnQgc2FmZWxlbmd0aCA9IDA7CgkgICAgU3RyaW5nQnVmZmVyIHNhZmV0ZXh0OwoJICAgIGludCBzYWZlb2Zmc2V0ID0gdGV4dG9mZnNldDsKCQoJICAgIGlmICh0ZXh0b2Zmc2V0ID4gbV90ZXh0QmVnaW5PZmZzZXRfCgkgICAgCSYmIG1fY29sbGF0b3JfLmlzVW5zYWZlKG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18uY2hhckF0KAoJICAgIAkJCQkJCQltX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfLmxlbmd0aCgpIC0gMSkpKSB7CgkgICAgICAgIHNhZmVvZmZzZXQgPSBnZXROZXh0U2FmZU9mZnNldCh0ZXh0b2Zmc2V0LCBtX3RleHRMaW1pdE9mZnNldF8pOwoJICAgICAgICBzYWZlbGVuZ3RoID0gc2FmZW9mZnNldCAtIHRleHRvZmZzZXQ7CgkgICAgICAgIHNhZmV0ZXh0ID0gbWVyZ2UobV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXywgdGFyZ2V0VGV4dCwgdGV4dG9mZnNldCwgCgkgICAgICAgIAkJCQkgc2FmZW9mZnNldCwgbnVsbCk7CgkgICAgfQoJICAgIGVsc2UgewoJICAgICAgICBzYWZldGV4dCA9IG1fY2Fub25pY2FsUHJlZml4QWNjZW50c187CgkgICAgfQoJCgkgICAgLy8gaWYgc3RhdHVzIGlzIGEgZmFpbHVyZSwgdWNvbF9zZXRUZXh0IGRvZXMgbm90aGluZwoJICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBjb2xlaXRlciA9IG1fdXRpbENvbEVJdGVyXzsKCSAgICBjb2xlaXRlci5zZXRUZXh0KHNhZmV0ZXh0LnRvU3RyaW5nKCkpOwoJICAgIC8vIHN0YXR1cyBjaGVja2VkIGluIGxvb3AgYmVsb3cKCSAgICAKCSAgICBpbnQgY2VpbmRleCA9IDA7CgkgICAgYm9vbGVhbiBpc1NhZmUgPSB0cnVlOyAvLyBzYWZlIHpvbmUgaW5kaWNhdGlvbiBmbGFnIGZvciBwb3NpdGlvbgoJICAgIGludCBwcmVmaXhsZW5ndGggPSBtX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfLmxlbmd0aCgpOwoJICAgIAoJICAgIHdoaWxlIChjZWluZGV4IDwgbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXykgewoJICAgICAgICBpbnQgdGV4dGNlID0gY29sZWl0ZXIubmV4dCgpOwoJICAgICAgICBpZiAodGV4dGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKCSAgICAgICAgICAgIC8vIGNoZWNrIGlmIHdlIGhhdmUgcGFzc2VkIHRoZSBzYWZlIGJ1ZmZlcgoJICAgICAgICAgICAgaWYgKGNvbGVpdGVyID09IG1fY29sRUl0ZXJfKSB7CgkgICAgICAgICAgICAgICAgcmV0dXJuIERPTkU7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAoc2FmZXRleHQgIT0gbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXykgewoJICAgICAgICAgICAgCXNhZmV0ZXh0LmRlbGV0ZSgwLCBzYWZldGV4dC5sZW5ndGgoKSk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBjb2xlaXRlciA9IG1fY29sRUl0ZXJfOwoJICAgICAgICAgICAgY29sZWl0ZXIuc2V0RXhhY3RPZmZzZXQoc2FmZW9mZnNldCk7CgkgICAgICAgICAgICAvLyBzdGF0dXMgY2hlY2tlZCBhdCB0aGUgc3RhcnQgb2YgdGhlIGxvb3AKCSAgICAgICAgICAgIGlzU2FmZSA9IGZhbHNlOwoJICAgICAgICAgICAgY29udGludWU7CgkgICAgICAgIH0KCSAgICAgICAgdGV4dGNlID0gZ2V0Q0UodGV4dGNlKTsKCSAgICAgICAgaWYgKHRleHRjZSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFIAoJICAgICAgICAJJiYgdGV4dGNlICE9IG1fcGF0dGVybl8ubV9DRV9bY2VpbmRleF0pIHsKCSAgICAgICAgICAgIC8vIGRvIHRoZSBiZWdpbm5pbmcgc3R1ZmYKCSAgICAgICAgICAgIGludCBmYWlsZWRvZmZzZXQgPSBjb2xlaXRlci5nZXRPZmZzZXQoKTsKCSAgICAgICAgICAgIGlmIChpc1NhZmUgJiYgZmFpbGVkb2Zmc2V0IDw9IHByZWZpeGxlbmd0aCkgewoJICAgICAgICAgICAgICAgIC8vIGFsYXMuLi4gbm8gaG9wZS4gZmFpbGVkIGF0IHJlYXJyYW5nZWQgYWNjZW50IHNldAoJICAgICAgICAgICAgICAgIHJldHVybiBET05FOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgZWxzZSB7CgkgICAgICAgICAgICAgICAgaWYgKGlzU2FmZSkgewoJICAgICAgICAgICAgICAgICAgICBmYWlsZWRvZmZzZXQgPSBzYWZlb2Zmc2V0IC0gZmFpbGVkb2Zmc2V0OwoJICAgICAgICAgICAgICAgICAgICBpZiAoc2FmZXRleHQgIT0gbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXykgewoJICAgICAgICAgICAgCQkJc2FmZXRleHQuZGVsZXRlKDAsIHNhZmV0ZXh0Lmxlbmd0aCgpKTsKCSAgICAgICAgICAgIAkJfQoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICAKCSAgICAgICAgICAgICAgICAvLyB0cnkgcmVhcnJhbmdpbmcgdGhlIGVuZCBhY2NlbnRzCgkgICAgICAgICAgICAgICAgaW50IHJlc3VsdCA9IGRvUHJldmlvdXNDYW5vbmljYWxTdWZmaXhNYXRjaCh0ZXh0b2Zmc2V0LCAKCSAgICAgICAgICAgICAgICAJCQkJCQkJCQkJCWZhaWxlZG9mZnNldCk7CgkgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSBET05FKSB7CgkgICAgICAgICAgICAgICAgICAgIC8vIGlmIHN0YXR1cyBpcyBhIGZhaWx1cmUsIHVjb2xfc2V0T2Zmc2V0IGRvZXMgbm90aGluZwoJICAgICAgICAgICAgICAgICAgICBtX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldChyZXN1bHQpOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgICAgIGlmICh0ZXh0Y2UgPT0gbV9wYXR0ZXJuXy5tX0NFX1tjZWluZGV4XSkgewoJICAgICAgICAgICAgY2VpbmRleCArKzsKCSAgICAgICAgfQoJICAgIH0KCSAgICAvLyBzZXQgb2Zmc2V0IGhlcmUKCSAgICBpZiAoaXNTYWZlKSB7CgkgICAgICAgIGludCByZXN1bHQgPSBjb2xlaXRlci5nZXRPZmZzZXQoKTsKCSAgICAgICAgLy8gc2V0cyB0aGUgdGV4dCBpdGVyYXRvciBoZXJlIHdpdGggdGhlIGNvcnJlY3QgZXhwYW5zaW9uIGFuZCBvZmZzZXQKCSAgICAgICAgaW50IGxlZnRvdmVyY2VzID0gY29sZWl0ZXIubV9DRUJ1ZmZlclNpemVfIAoJICAgICAgICAJCQkJCQkJCQktIGNvbGVpdGVyLm1fQ0VCdWZmZXJPZmZzZXRfOwoJICAgICAgICBpZiAocmVzdWx0IDw9IHByZWZpeGxlbmd0aCkgeyAKCSAgICAgICAgICAgIHJlc3VsdCA9IHRleHRvZmZzZXQ7CgkgICAgICAgIH0KCSAgICAgICAgZWxzZSB7CgkgICAgICAgICAgICByZXN1bHQgPSB0ZXh0b2Zmc2V0ICsgKHNhZmVvZmZzZXQgLSByZXN1bHQpOwoJICAgICAgICB9CgkgICAgICAgIG1fY29sRUl0ZXJfLnNldEV4YWN0T2Zmc2V0KHJlc3VsdCk7CgkgICAgICAgIG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJPZmZzZXRfID0gbV9jb2xFSXRlcl8ubV9DRUJ1ZmZlclNpemVfIAoJICAgICAgICAJCQkJCQkJCQkJCQkJLSBsZWZ0b3ZlcmNlczsKCSAgICAgICAgcmV0dXJuIHJlc3VsdDsKCSAgICB9CgkgICAgCgkgICAgcmV0dXJuIGNvbGVpdGVyLmdldE9mZnNldCgpOyAgICAgICAgICAgICAgCgl9CgkKCS8qKgoJICogVHJ5aW5nIG91dCB0aGUgc3Vic3RyaW5nIGFuZCBzZWVzIGlmIGl0IGNhbiBiZSBhIGNhbm9uaWNhbCBtYXRjaC4KCSAqIFRoaXMgd2lsbCB0cnkgbm9ybWFsaXppbmcgdGhlIHN0YXJ0aW5nIGFjY2VudHMgYW5kIGFycmFuZ2luZyB0aGVtIGludG8gCgkgKiBjYW5vbmljYWwgZXF1aXZhbGVudHMgYW5kIGNoZWNrIHRoZWlyIGNvcnJlc3BvbmRpbmcgY2VzIHdpdGggdGhlIHBhdHRlcm4gCgkgKiBjZS4KCSAqIFByZWZpeCBhY2NlbnRzIGluIHRoZSB0ZXh0IHdpbGwgYmUgZ3JvdXBlZCBhY2NvcmRpbmcgdG8gdGhlaXIgY29tYmluaW5nIAoJICogY2xhc3MgYW5kIHRoZSBncm91cHMgd2lsbCBiZSBtaXhlZCBhbmQgbWF0Y2hlZCB0byB0cnkgZmluZCB0aGUgcGVyZmVjdCAKCSAqIG1hdGNoIHdpdGggdGhlIHBhdHRlcm4uCgkgKiBTbyBmb3IgaW5zdGFuY2UgbG9va2luZyBmb3IgIlx1MDMwMSIgaW4gIlx1MDMwQVx1MDMwMVx1MDMyNSIKCSAqIHN0ZXAgMTogc3BsaXQgIlx1MDMwQVx1MDMwMSIgaW50byA2IG90aGVyIHR5cGUgb2YgcG90ZW50aWFsIGFjY2VudCAKCSAqIAkJICAgc3Vic3RyaW5ncwoJICogICAgICAgICAiXHUwMzBBIiwgIlx1MDMwMSIsICJcdTAzMjUiLCAiXHUwMzBBXHUwMzAxIiwgIlx1MDMwQVx1MDMyNSIsIAoJICogICAgICAgICAiXHUwMzAxXHUwMzI1Ii4KCSAqIHN0ZXAgMjogY2hlY2sgaWYgYW55IG9mIHRoZSBnZW5lcmF0ZWQgc3Vic3RyaW5ncyBtYXRjaGVzIHRoZSBwYXR0ZXJuLgoJICogQHBhcmFtIHRleHRvZmZzZXQgc3RhcnQgb2Zmc2V0IGluIHRoZSBjb2xsYXRpb24gZWxlbWVudCB0ZXh0IHRoYXQgc3RhcnRzIAoJICogICAgICAgICAgICAgICAgICAgd2l0aCB0aGUgYWNjZW50cyB0byBiZSByZWFycmFuZ2VkCgkgKiBAcmV0dXJuIHRydWUgaWYgdGhlIG1hdGNoIGlzIHZhbGlkLCBmYWxzZSBvdGhlcndpc2UKCSAqLwoJcHJpdmF0ZSBib29sZWFuIGRvUHJldmlvdXNDYW5vbmljYWxNYXRjaChpbnQgdGV4dG9mZnNldCkKCXsKICAgICAgICBpbnQgb2Zmc2V0ID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CgkgICAgaWYgKChnZXRGQ0QodGFyZ2V0VGV4dCwgdGV4dG9mZnNldCkgPj4gU0VDT05EX0xBU1RfQllURV9TSElGVF8pID09IDApIHsKCSAgICAgICAgaWYgKG1fcGF0dGVybl8ubV9oYXNTdWZmaXhBY2NlbnRzXykgewoJICAgICAgICAgICAgb2Zmc2V0ID0gZG9QcmV2aW91c0Nhbm9uaWNhbFN1ZmZpeE1hdGNoKHRleHRvZmZzZXQsIG9mZnNldCk7CgkgICAgICAgICAgICBpZiAob2Zmc2V0ICE9IERPTkUpIHsKCSAgICAgICAgICAgICAgICBtX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldChvZmZzZXQpOwoJICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICB9CgkKCSAgICBpZiAoIW1fcGF0dGVybl8ubV9oYXNQcmVmaXhBY2NlbnRzXykgewoJICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgfQoJCgkgICAgU3RyaW5nQnVmZmVyIGFjY2VudHMgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CgkgICAgLy8gb2Zmc2V0IHRvIHRoZSBsYXN0IGJhc2UgY2hhcmFjdGVyIGluIHN1YnN0cmluZyB0byBzZWFyY2gKCSAgICBpbnQgYmFzZW9mZnNldCA9IGdldE5leHRCYXNlT2Zmc2V0KHRhcmdldFRleHQsIHRleHRvZmZzZXQpOwoJICAgIC8vIG5vcm1hbGl6aW5nIHRoZSBvZmZlbnNpdmUgc3RyaW5nCgkgICAgU3RyaW5nIHRleHRzdHIgPSBnZXRTdHJpbmcodGFyZ2V0VGV4dCwgdGV4dG9mZnNldCwgCgkgICAgCQkJCQkJCQkJCQliYXNlb2Zmc2V0IC0gdGV4dG9mZnNldCk7CgkgICAgaWYgKE5vcm1hbGl6ZXIucXVpY2tDaGVjayh0ZXh0c3RyLCBOb3JtYWxpemVyLk5GRCkgCgkgICAgICAgIAkJCQkJCQkJCQk9PSBOb3JtYWxpemVyLk5PKSB7CgkgICAgICAgIHRleHRzdHIgPSBOb3JtYWxpemVyLmRlY29tcG9zZSh0ZXh0c3RyLCBmYWxzZSk7CgkgICAgfQoJICAgIGFjY2VudHMuYXBwZW5kKHRleHRzdHIpOwoJICAgIC8vIHN0YXR1cyBjaGVja2VkIGluIGxvb3AKCSAgICAgICAgCgkgICAgaW50IGFjY2VudHNpbmRleFtdID0gbmV3IGludFtJTklUSUFMX0FSUkFZX1NJWkVfXTsKCSAgICBpbnQgc2l6ZSA9IGdldFVuYmxvY2tlZEFjY2VudEluZGV4KGFjY2VudHMsIGFjY2VudHNpbmRleCk7CgkKCSAgICAvLyAyIHBvd2VyIG4gLSAxIG1pbnVzIHRoZSBmdWxsIHNldCBvZiBhY2NlbnRzCgkgICAgaW50IGNvdW50ID0gKDIgPDwgKHNpemUgLSAxKSkgLSAyOyAgCgkgICAgd2hpbGUgKGNvdW50ID4gMCkgewoJICAgIAltX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfLmRlbGV0ZSgwLCAKCSAgICAJCQkJCQkJCW1fY2Fub25pY2FsUHJlZml4QWNjZW50c18ubGVuZ3RoKCkpOwoJICAgICAgICAvLyBjb3B5IHRoZSBiYXNlIGNoYXJhY3RlcnMKCSAgICAgICAgZm9yIChpbnQgayA9IDA7IGsgPCBhY2NlbnRzaW5kZXhbMF07IGsgKyspIHsKCSAgICAgICAgICAgIG1fY2Fub25pY2FsUHJlZml4QWNjZW50c18uYXBwZW5kKGFjY2VudHMuY2hhckF0KGspKTsKCSAgICAgICAgfQoJICAgICAgICAvLyBmb3JtaW5nIGFsbCBwb3NzaWJsZSBjYW5vbmljYWwgcmVhcnJhbmdlbWVudCBieSBkcm9wcGluZwoJICAgICAgICAvLyBzZXRzIG9mIGFjY2VudHMKCSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gc2l6ZSAtIDE7IGkgKyspIHsKCSAgICAgICAgICAgIGludCBtYXNrID0gMSA8PCAoc2l6ZSAtIGkgLSAxKTsKCSAgICAgICAgICAgIGlmICgoY291bnQgJiBtYXNrKSAhPSAwKSB7CgkgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IGFjY2VudHNpbmRleFtpXTsgaiA8IGFjY2VudHNpbmRleFtpICsgMV07IAoJICAgICAgICAgICAgICAgIAkgaiArKykgewoJICAgICAgICAgICAgICAgICAgICBtX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfLmFwcGVuZChhY2NlbnRzLmNoYXJBdChqKSk7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgICAgIG9mZnNldCA9IGRvUHJldmlvdXNDYW5vbmljYWxQcmVmaXhNYXRjaChiYXNlb2Zmc2V0KTsKCSAgICAgICAgaWYgKG9mZnNldCAhPSBET05FKSB7CgkgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gbWF0Y2ggZm91bmQKCSAgICAgICAgfQoJICAgICAgICBjb3VudCAtLTsKCSAgICB9CgkgICAgcmV0dXJuIGZhbHNlOwoJfQoJCgkvKioKCSAqIENoZWNrcyBtYXRjaCBmb3IgY29udHJhY3Rpb24uIAoJICogSWYgdGhlIG1hdGNoIHN0YXJ0cyB3aXRoIGEgcGFydGlhbCBjb250cmFjdGlvbiB3ZSBmYWlsLgoJICogVXNlcyB0aGUgdGVtcG9yYXJ5IHV0aWxpdHkgYnVmZmVyIHRvIHJldHVybiB0aGUgbW9kaWZpZWQgc3RhcnQgYW5kIGVuZC4KCSAqIEBwYXJhbSBzdGFydCBvZmZzZXQgb2YgcG90ZW50aWFsIG1hdGNoLCB0byBiZSBtb2RpZmllZCBpZiBuZWNlc3NhcnkKCSAqIEBwYXJhbSBlbmQgb2Zmc2V0IG9mIHBvdGVudGlhbCBtYXRjaCwgdG8gYmUgbW9kaWZpZWQgaWYgbmVjZXNzYXJ5CgkgKiBAcmV0dXJuIHRydWUgaWYgbWF0Y2ggcGFzc2VzIHRoZSBjb250cmFjdGlvbiB0ZXN0LCBmYWxzZSBvdGhlcndpc2UuCgkgKi8KCXByaXZhdGUgYm9vbGVhbiBjaGVja1ByZXZpb3VzQ2Fub25pY2FsQ29udHJhY3Rpb25NYXRjaChpbnQgc3RhcnQsIGludCBlbmQpIAoJewoJICAgIGludCB0ZW1wID0gZW5kOwoJICAgIC8vIFRoaXMgcGFydCBjaGVja3MgaWYgZWl0aGVyIGVuZHMgb2YgdGhlIG1hdGNoIGNvbnRhaW5zIHBvdGVudGlhbCAKCSAgICAvLyBjb250cmFjdGlvbi4gSWYgc28gd2UnbGwgaGF2ZSB0byBpdGVyYXRlIHRocm91Z2ggdGhlbQoJICAgIGNoYXIgZWNoYXIgPSAwOwoJICAgIGNoYXIgc2NoYXIgPSAwOwoJICAgIGlmIChlbmQgPCBtX3RleHRMaW1pdE9mZnNldF8pIHsKCSAgICAJdGFyZ2V0VGV4dC5zZXRJbmRleChlbmQpOwoJICAgIAllY2hhciA9IHRhcmdldFRleHQuY3VycmVudCgpOwoJICAgIH0KCSAgICBpZiAoc3RhcnQgKyAxIDwgbV90ZXh0TGltaXRPZmZzZXRfKSB7CgkgICAgCXRhcmdldFRleHQuc2V0SW5kZXgoc3RhcnQgKyAxKTsKCSAgICAJc2NoYXIgPSB0YXJnZXRUZXh0LmN1cnJlbnQoKTsKCSAgICB9CgkgICAgaWYgKG1fY29sbGF0b3JfLmlzVW5zYWZlKGVjaGFyKSB8fCBtX2NvbGxhdG9yXy5pc1Vuc2FmZShzY2hhcikpIHsKCSAgICAgICAgaW50IGV4cGFuc2lvbiA9IG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJTaXplXyAKCSAgICAgICAgCQkJCQkJCQktIG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJPZmZzZXRfOwoJICAgICAgICBib29sZWFuIGhhc0V4cGFuc2lvbiA9IGV4cGFuc2lvbiA+IDA7CgkgICAgICAgIG1fY29sRUl0ZXJfLnNldEV4YWN0T2Zmc2V0KGVuZCk7CgkgICAgICAgIHdoaWxlIChleHBhbnNpb24gPiAwKSB7CgkgICAgICAgICAgICAvLyBnZXR0aW5nIHJpZCBvZiB0aGUgcmVkdW5kYW50IGNlCgkgICAgICAgICAgICAvLyBzaW5jZSBmb3J3YXJkIGNvbnRyYWN0aW9uL2V4cGFuc2lvbiBtYXkgaGF2ZSBleHRyYSBjZXMKCSAgICAgICAgICAgIC8vIGlmIHdlIGFyZSBpbiB0aGUgbm9ybWFsaXphdGlvbiBidWZmZXIsIGhhc0FjY2VudHNCZWZvcmVNYXRjaAoJICAgICAgICAgICAgLy8gd291bGQgaGF2ZSB0YWtlbiBjYXJlIG9mIGl0LgoJICAgICAgICAgICAgLy8gRS5nLiB0aGUgY2hhcmFjdGVyIFx1MDFGQSB3aWxsIGhhdmUgYW4gZXhwYW5zaW9uIG9mIDMsIGJ1dCAKCSAgICAgICAgICAgIC8vIGlmIHdlIGFyZSBvbmx5IGxvb2tpbmcgZm9yIEEgcmluZyBBXHUwMzBBLCB3ZSdsbCBoYXZlIHRvIAoJICAgICAgICAgICAgLy8gc2tpcCB0aGUgbGFzdCBjZSBpbiB0aGUgZXhwYW5zaW9uIGJ1ZmZlcgoJICAgICAgICAgICAgbV9jb2xFSXRlcl8ucHJldmlvdXMoKTsKCSAgICAgICAgICAgIGlmIChtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKSAhPSB0ZW1wKSB7CgkgICAgICAgICAgICAgICAgZW5kID0gdGVtcDsKCSAgICAgICAgICAgICAgICB0ZW1wID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBleHBhbnNpb24gLS07CgkgICAgICAgIH0KCQoJICAgICAgICBpbnQgY291bnQgPSBtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfOwoJICAgICAgICB3aGlsZSAoY291bnQgPiAwKSB7CgkgICAgICAgICAgICBpbnQgY2UgPSBnZXRDRShtX2NvbEVJdGVyXy5wcmV2aW91cygpKTsKCSAgICAgICAgICAgIC8vIHN0YXR1cyBjaGVja2VkIGJlbG93LCBub3RlIHRoYXQgaWYgc3RhdHVzIGlzIGEgZmFpbHVyZQoJICAgICAgICAgICAgLy8gcHJldmlvdXMoKSByZXR1cm5zIE5VTExPUkRFUgoJICAgICAgICAgICAgaWYgKGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGlmIChoYXNFeHBhbnNpb24gJiYgY291bnQgPT0gMCAKCSAgICAgICAgICAgIAkmJiBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKSAhPSB0ZW1wKSB7CgkgICAgICAgICAgICAgICAgZW5kID0gdGVtcDsKCSAgICAgICAgICAgICAgICB0ZW1wID0gbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAoY291bnQgPT0gbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyAKCSAgICAgICAgICAgIAkmJiBjZSAhPSBtX3BhdHRlcm5fLm1fQ0VfW21fcGF0dGVybl8ubV9DRUxlbmd0aF8gLSAxXSkgewoJICAgICAgICAgICAgICAgIC8vIGFjY2VudHMgbWF5IGhhdmUgZXh0cmEgc3RhcnRpbmcgY2VzLCB0aGlzIG9jY3VycyB3aGVuIGEgCgkgICAgICAgICAgICAgICAgLy8gcHVyZSBhY2NlbnQgcGF0dGVybiBpcyBtYXRjaGVkIHdpdGhvdXQgcmVhcnJhbmdlbWVudAoJICAgICAgICAgICAgICAgIGludCBleHBlY3RlZCA9IG1fcGF0dGVybl8ubV9DRV9bbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyAtIDFdOwoJICAgICAgICAgICAgICAgIHRhcmdldFRleHQuc2V0SW5kZXgoZW5kKTsKCSAgICAgICAgICAgICAgICBpZiAoVVRGMTYuaXNUcmFpbFN1cnJvZ2F0ZSh0YXJnZXRUZXh0LnByZXZpb3VzKCkpKSB7CgkgICAgICAgICAgICAgICAgCWlmICh0YXJnZXRUZXh0LmdldEluZGV4KCkgPiBtX3RleHRCZWdpbk9mZnNldF8gJiYKCSAgICAgICAgICAgICAgICAJCSFVVEYxNi5pc0xlYWRTdXJyb2dhdGUodGFyZ2V0VGV4dC5wcmV2aW91cygpKSkgewoJICAgICAgICAgICAgICAgIAkJdGFyZ2V0VGV4dC5uZXh0KCk7CgkgICAgICAgICAgICAgICAgCX0KCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgZW5kID0gdGFyZ2V0VGV4dC5nZXRJbmRleCgpOwoJICAgICAgICAgICAgICAgIGlmICgoZ2V0RkNEKHRhcmdldFRleHQsIGVuZCkgJiBMQVNUX0JZVEVfTUFTS18pICE9IDApIHsKCSAgICAgICAgICAgICAgICAgICAgY2UgPSBnZXRDRShtX2NvbEVJdGVyXy5wcmV2aW91cygpKTsKCSAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGNlICE9IGV4cGVjdGVkIAoJICAgICAgICAgICAgICAgICAgICAJCSYmIGNlICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIgCgkgICAgICAgICAgICAgICAgICAgIAkJJiYgbV9jb2xFSXRlcl8uZ2V0T2Zmc2V0KCkgPD0gc3RhcnQpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIGNlID0gZ2V0Q0UobV9jb2xFSXRlcl8ucHJldmlvdXMoKSk7CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAoY2UgIT0gbV9wYXR0ZXJuXy5tX0NFX1tjb3VudCAtIDFdKSB7CgkgICAgICAgICAgICAgICAgc3RhcnQgLS07CgkgICAgICAgICAgICAgICAgc3RhcnQgPSBnZXRQcmV2aW91c0Jhc2VPZmZzZXQoc3RhcnQpOwoJICAgICAgICAgICAgICAgIG1fdXRpbEJ1ZmZlcl9bMF0gPSBzdGFydDsKCSAgICAgICAgICAgICAgICBtX3V0aWxCdWZmZXJfWzFdID0gZW5kOwoJICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGNvdW50IC0tOwoJICAgICAgICB9CgkgICAgfSAKCSAgICBtX3V0aWxCdWZmZXJfWzBdID0gc3RhcnQ7CgkgICAgbV91dGlsQnVmZmVyX1sxXSA9IGVuZDsKCSAgICByZXR1cm4gdHJ1ZTsKCX0KCQoJLyoqCgkgKiBDaGVja3MgYW5kIHNldHMgdGhlIG1hdGNoIGluZm9ybWF0aW9uIGlmIGZvdW5kLgoJICogQ2hlY2tzIAoJICogPHVsPgoJICogPGxpPiB0aGUgcG90ZW50aWFsIG1hdGNoIGRvZXMgbm90IHJlcGVhdCB0aGUgcHJldmlvdXMgbWF0Y2gKCSAqIDxsaT4gYm91bmRhcmllcyBhcmUgY29ycmVjdAoJICogPGxpPiBwb3RlbnRpYWwgbWF0Y2ggZG9lcyBub3QgZW5kIGluIHRoZSBtaWRkbGUgb2YgYSBjb250cmFjdGlvbgoJICogPGxpPiBpZGVudGljYWwgbWF0Y2hlcwoJICogPC91bD4KCSAqIE90aGVyd2lzZSB0aGUgb2Zmc2V0IHdpbGwgYmUgc2hpZnRlZCB0byB0aGUgbmV4dCBjaGFyYWN0ZXIuCgkgKiBVc2VzIHRoZSB0ZW1wb3JhcnkgdXRpbGl0eSBidWZmZXIgZm9yIHN0b3JpbmcgdGhlIG1vZGlmaWVkIHRleHRvZmZzZXQuCgkgKiBAcGFyYW0gdGV4dG9mZnNldCBvZmZzZXQgaW4gdGhlIGNvbGxhdGlvbiBlbGVtZW50IHRleHQuIHRoZSByZXR1cm5lZCAKCSAqIAkJCXZhbHVlIHdpbGwgYmUgdGhlIHRydW5jYXRlZCBzdGFydCBvZmZzZXQgb2YgdGhlIG1hdGNoIG9yIHRoZSAKCSAqIAkJCW5ldyBzdGFydCBzZWFyY2ggb2Zmc2V0LgoJICogQHJldHVybiB0cnVlIGlmIHRoZSBtYXRjaCBpcyB2YWxpZCwgZmFsc2Ugb3RoZXJ3aXNlCgkgKi8KCXByaXZhdGUgYm9vbGVhbiBjaGVja1ByZXZpb3VzQ2Fub25pY2FsTWF0Y2goaW50IHRleHRvZmZzZXQpCgl7CgkgICAgLy8gdG8gZW5zdXJlIHRoYXQgdGhlIHN0YXJ0IGFuZCBlbmRzIGFyZSBub3QgY29tcG9zaXRlIGNoYXJhY3RlcnMKCSAgICAvLyBpZiB3ZSBoYXZlIGEgY2Fub25pY2FsIGFjY2VudCBtYXRjaAoJICAgIGlmIChtX3BhdHRlcm5fLm1faGFzU3VmZml4QWNjZW50c18gCgkgICAgCSYmIG1fY2Fub25pY2FsU3VmZml4QWNjZW50c18ubGVuZ3RoKCkgIT0gMCAKCSAgICAJfHwgbV9wYXR0ZXJuXy5tX2hhc1ByZWZpeEFjY2VudHNfIAoJICAgIAkmJiBtX2Nhbm9uaWNhbFByZWZpeEFjY2VudHNfLmxlbmd0aCgpICE9IDApIHsKCSAgICAgICAgbV9tYXRjaGVkSW5kZXhfID0gdGV4dG9mZnNldDsKCSAgICAgICAgbWF0Y2hMZW5ndGggPSBnZXROZXh0QmFzZU9mZnNldChtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKSkgCgkgICAgICAgICAgICAJCQkJCQkJCQkJCQktIHRleHRvZmZzZXQ7CgkgICAgICAgIHJldHVybiB0cnVlOwoJICAgIH0KCQoJICAgIGludCBlbmQgPSBtX2NvbEVJdGVyXy5nZXRPZmZzZXQoKTsKCSAgICBpZiAoIWNoZWNrUHJldmlvdXNDYW5vbmljYWxDb250cmFjdGlvbk1hdGNoKHRleHRvZmZzZXQsIGVuZCkpIHsKCSAgICAJLy8gc3RvcmluZyB0aGUgbW9kaWZpZWQgdGV4dG9mZnNldAoJICAgIAlyZXR1cm4gZmFsc2U7CgkgICAgfQoJICAgIHRleHRvZmZzZXQgPSBtX3V0aWxCdWZmZXJfWzBdOwoJCWVuZCA9IG1fdXRpbEJ1ZmZlcl9bMV07CgkgICAgZW5kID0gZ2V0TmV4dEJhc2VPZmZzZXQoZW5kKTsKCSAgICAvLyB0aGlzIHRvdGFsbHkgbWF0Y2hlcywgaG93ZXZlciB3ZSBuZWVkIHRvIGNoZWNrIGlmIGl0IGlzIHJlcGVhdGluZwoJICAgIGlmIChjaGVja1JlcGVhdGVkTWF0Y2godGV4dG9mZnNldCwgZW5kKSAKCSAgICAJfHwgIWlzQnJlYWtVbml0KHRleHRvZmZzZXQsIGVuZCkgCgkgICAgCXx8ICFjaGVja0lkZW50aWNhbCh0ZXh0b2Zmc2V0LCBlbmQpKSB7CgkgICAgICAgIHRleHRvZmZzZXQgLS07CgkgICAgICAgIHRleHRvZmZzZXQgPSBnZXRQcmV2aW91c0Jhc2VPZmZzZXQodGV4dG9mZnNldCk7CgkgICAgICAgIG1fdXRpbEJ1ZmZlcl9bMF0gPSB0ZXh0b2Zmc2V0OwoJICAgICAgICByZXR1cm4gZmFsc2U7CgkgICAgfQoJICAgIAoJICAgIG1fbWF0Y2hlZEluZGV4XyA9IHRleHRvZmZzZXQ7CgkgICAgbWF0Y2hMZW5ndGggPSBlbmQgLSB0ZXh0b2Zmc2V0OwoJICAgIHJldHVybiB0cnVlOwoJfQoJCgkvKioKCSAqIE1ldGhvZCB0aGF0IGRvZXMgdGhlIG5leHQgZXhhY3QgbWF0Y2gKCSAqIEBwYXJhbSBzdGFydCB0aGUgb2Zmc2V0IHRvIHN0YXJ0IHNoaWZ0aW5nIGZyb20gYW5kIHBlcmZvcm1pbmcgdGhlIAoJICogICAgICAgIG5leHQgZXhhY3QgbWF0Y2gKCSAqLwoJcHJpdmF0ZSB2b2lkIGhhbmRsZU5leHRFeGFjdChpbnQgc3RhcnQpCgl7CgkgICAJaW50IHRleHRvZmZzZXQgPSBzaGlmdEZvcndhcmQoc3RhcnQsIAoJICAgCQkJCQkJCQkgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIsCgkgICAJCQkJCQkJCSAgbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyk7CgkJaW50IHRhcmdldGNlID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRTsKCSAgICB3aGlsZSAodGV4dG9mZnNldCA8PSBtX3RleHRMaW1pdE9mZnNldF8pIHsKICAgICAgICAgICAgbV9jb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQodGV4dG9mZnNldCk7CgkgICAgICAgIGludCBwYXR0ZXJuY2VpbmRleCA9IG1fcGF0dGVybl8ubV9DRUxlbmd0aF8gLSAxOwoJICAgICAgICBib29sZWFuIGZvdW5kID0gZmFsc2U7CgkgICAgICAgIGludCBsYXN0Y2UgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSOwoJICAgICAgICAKCSAgICAgICAgd2hpbGUgKHRydWUpIHsKCSAgICAgICAgICAgIC8vIGZpbmRpbmcgdGhlIGxhc3QgcGF0dGVybiBjZSBtYXRjaCwgaW1hZ2luZSBjb21wb3NpdGUgCgkgICAgICAgICAgICAvLyBjaGFyYWN0ZXJzLiBmb3IgZXhhbXBsZTogc2VhcmNoIGZvciBwYXR0ZXJuIEEgaW4gdGV4dCBcdTAwQzAKCSAgICAgICAgICAgIC8vIHdlJ2xsIGhhdmUgdG8gc2tpcCBcdTAzMDAgdGhlIGdyYXZlIGZpcnN0IGJlZm9yZSB3ZSBnZXQgdG8gQQoJICAgICAgICAgICAgdGFyZ2V0Y2UgPSBtX2NvbEVJdGVyXy5wcmV2aW91cygpOwoJICAgICAgICAgICAgaWYgKHRhcmdldGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKCSAgICAgICAgICAgICAgICBmb3VuZCA9IGZhbHNlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgdGFyZ2V0Y2UgPSBnZXRDRSh0YXJnZXRjZSk7CgkgICAgICAgICAgICBpZiAodGFyZ2V0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSAmJiAKCSAgICAgICAgICAgIAltX2NvbEVJdGVyXy5pc0luQnVmZmVyKCkpIHsgCgkgICAgICAgICAgICAgICAgLy8gdGhpcyBpcyBmb3IgdGhlIHRleHQgXHUwMzE1XHUwMzAwIHRoYXQgcmVxdWlyZXMgCgkgICAgICAgICAgICAgICAgLy8gbm9ybWFsaXphdGlvbiBhbmQgcGF0dGVybiBcdTAzMDAsIHdoZXJlIFx1MDMxNSBpcyBpZ25vcmFibGUKCSAgICAgICAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGlmIChsYXN0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUiAKCSAgICAgICAgICAgIAl8fCBsYXN0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgICAgIGxhc3RjZSA9IHRhcmdldGNlOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKHRhcmdldGNlID09IG1fcGF0dGVybl8ubV9DRV9bcGF0dGVybmNlaW5kZXhdKSB7CgkgICAgICAgICAgICAgICAgLy8gdGhlIGZpcnN0IGNlIGNhbiBiZSBhIGNvbnRyYWN0aW9uCgkgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJPZmZzZXRfIDw9IDApIHsKCSAgICAgICAgICAgICAgICBmb3VuZCA9IGZhbHNlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkKCSAgICAgICAgdGFyZ2V0Y2UgPSBsYXN0Y2U7CgkgICAgICAgIAoJICAgICAgICB3aGlsZSAoZm91bmQgJiYgcGF0dGVybmNlaW5kZXggPiAwKSB7CgkgICAgICAgICAgICB0YXJnZXRjZSA9IG1fY29sRUl0ZXJfLnByZXZpb3VzKCk7CgkgICAgICAgICAgICBpZiAodGFyZ2V0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewoJICAgICAgICAgICAgICAgIGZvdW5kID0gZmFsc2U7CgkgICAgICAgICAgICAgICAgYnJlYWs7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICB0YXJnZXRjZSA9IGdldENFKHRhcmdldGNlKTsKCSAgICAgICAgICAgIGlmICh0YXJnZXRjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CgkgICAgICAgICAgICAgICAgY29udGludWU7CgkgICAgICAgICAgICB9CgkKCSAgICAgICAgICAgIHBhdHRlcm5jZWluZGV4IC0tOwoJICAgICAgICAgICAgZm91bmQgPSBmb3VuZCAmJiB0YXJnZXRjZSA9PSBtX3BhdHRlcm5fLm1fQ0VfW3BhdHRlcm5jZWluZGV4XTsgCgkgICAgICAgIH0KCQoJICAgICAgICBpZiAoIWZvdW5kKSB7CgkgICAgICAgICAgICB0ZXh0b2Zmc2V0ID0gc2hpZnRGb3J3YXJkKHRleHRvZmZzZXQsIHRhcmdldGNlLCAKCSAgICAgICAgICAgIAkJCQkJCQkJCQkJcGF0dGVybmNlaW5kZXgpOwoJICAgICAgICAgICAgLy8gc3RhdHVzIGNoZWNrZWQgYXQgbG9vcC4KCSAgICAgICAgICAgIHBhdHRlcm5jZWluZGV4ID0gbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXzsKCSAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICB9CgkgICAgICAgIAoJICAgICAgICBpZiAoY2hlY2tOZXh0RXhhY3RNYXRjaCh0ZXh0b2Zmc2V0KSkgewoJICAgICAgICAgICAgLy8gc3RhdHVzIGNoZWNrZWQgaW4gdWNvbF9zZXRPZmZzZXQKCSAgICAgICAgICAgIHJldHVybjsKCSAgICAgICAgfQoJICAgICAgICB0ZXh0b2Zmc2V0ID0gbV91dGlsQnVmZmVyX1swXTsKCSAgICB9CgkgICAgc2V0TWF0Y2hOb3RGb3VuZCgpOwoJfQoKCS8qKgoJICogTWV0aG9kIHRoYXQgZG9lcyB0aGUgbmV4dCBjYW5vbmljYWwgbWF0Y2gKCSAqIEBwYXJhbSBzdGFydCB0aGUgb2Zmc2V0IHRvIHN0YXJ0IHNoaWZ0aW5nIGZyb20gYW5kIHBlcmZvcm1pbmcgdGhlIAoJICogICAgICAgIG5leHQgY2Fub25pY2FsIG1hdGNoCgkgKi8KCXByaXZhdGUgdm9pZCBoYW5kbGVOZXh0Q2Fub25pY2FsKGludCBzdGFydCkKCXsKCSAgICBib29sZWFuIGhhc1BhdHRlcm5BY2NlbnRzID0gCgkgICAgICAgbV9wYXR0ZXJuXy5tX2hhc1N1ZmZpeEFjY2VudHNfIHx8IG1fcGF0dGVybl8ubV9oYXNQcmVmaXhBY2NlbnRzXzsKCSAgICAgICAgICAKCSAgICAvLyBzaGlmdGluZyBpdCBjaGVjayBmb3Igc2V0dGluZyBvZmZzZXQKCSAgICAvLyBpZiBzZXRPZmZzZXQgaXMgY2FsbGVkIHByZXZpb3VzbHkgb3IgdGhlcmUgd2FzIG5vIHByZXZpb3VzIG1hdGNoLCB3ZQoJICAgIC8vIGxlYXZlIHRoZSBvZmZzZXQgYXMgaXQgaXMuCgkgICAgaW50IHRleHRvZmZzZXQgPSBzaGlmdEZvcndhcmQoc3RhcnQsIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIsIAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCSAgbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyk7CgkgICAgbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5kZWxldGUoMCwgbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5sZW5ndGgoKSk7CgkgICAgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5kZWxldGUoMCwgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5sZW5ndGgoKSk7CgkJaW50IHRhcmdldGNlID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRTsKCSAgICAKCSAgICB3aGlsZSAodGV4dG9mZnNldCA8PSBtX3RleHRMaW1pdE9mZnNldF8pCgkgICAgewoJICAgIAltX2NvbEVJdGVyXy5zZXRFeGFjdE9mZnNldCh0ZXh0b2Zmc2V0KTsKCSAgICAgICAgaW50IHBhdHRlcm5jZWluZGV4ID0gbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyAtIDE7CgkgICAgICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKCSAgICAgICAgaW50IGxhc3RjZSA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVI7CgkgICAgICAgIAoJICAgICAgICB3aGlsZSAodHJ1ZSkgewoJICAgICAgICAgICAgLy8gZmluZGluZyB0aGUgbGFzdCBwYXR0ZXJuIGNlIG1hdGNoLCBpbWFnaW5lIGNvbXBvc2l0ZSBjaGFyYWN0ZXJzCgkgICAgICAgICAgICAvLyBmb3IgZXhhbXBsZTogc2VhcmNoIGZvciBwYXR0ZXJuIEEgaW4gdGV4dCBcdTAwQzAKCSAgICAgICAgICAgIC8vIHdlJ2xsIGhhdmUgdG8gc2tpcCBcdTAzMDAgdGhlIGdyYXZlIGZpcnN0IGJlZm9yZSB3ZSBnZXQgdG8gQQoJICAgICAgICAgICAgdGFyZ2V0Y2UgPSBtX2NvbEVJdGVyXy5wcmV2aW91cygpOwoJICAgICAgICAgICAgaWYgKHRhcmdldGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKCSAgICAgICAgICAgICAgICBmb3VuZCA9IGZhbHNlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgdGFyZ2V0Y2UgPSBnZXRDRSh0YXJnZXRjZSk7CgkgICAgICAgICAgICBpZiAobGFzdGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIgCgkgICAgICAgICAgICAJCQl8fCBsYXN0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgICAgIGxhc3RjZSA9IHRhcmdldGNlOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKHRhcmdldGNlID09IG1fcGF0dGVybl8ubV9DRV9bcGF0dGVybmNlaW5kZXhdKSB7CgkgICAgICAgICAgICAgICAgLy8gdGhlIGZpcnN0IGNlIGNhbiBiZSBhIGNvbnRyYWN0aW9uCgkgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJPZmZzZXRfIDw9IDApIHsKCSAgICAgICAgICAgICAgICBmb3VuZCA9IGZhbHNlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgICAgIHRhcmdldGNlID0gbGFzdGNlOwoJICAgICAgICAKCSAgICAgICAgd2hpbGUgKGZvdW5kICYmIHBhdHRlcm5jZWluZGV4ID4gMCkgewoJICAgICAgICAgICAgdGFyZ2V0Y2UgICAgPSBtX2NvbEVJdGVyXy5wcmV2aW91cygpOwoJICAgICAgICAgICAgaWYgKHRhcmdldGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5OVUxMT1JERVIpIHsKCSAgICAgICAgICAgICAgICBmb3VuZCA9IGZhbHNlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgdGFyZ2V0Y2UgICAgPSBnZXRDRSh0YXJnZXRjZSk7CgkgICAgICAgICAgICBpZiAodGFyZ2V0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICAgICAgfQoJCgkgICAgICAgICAgICBwYXR0ZXJuY2VpbmRleCAtLTsKCSAgICAgICAgICAgIGZvdW5kID0gZm91bmQgJiYgdGFyZ2V0Y2UgPT0gbV9wYXR0ZXJuXy5tX0NFX1twYXR0ZXJuY2VpbmRleF07IAoJICAgICAgICB9CgkKCSAgICAgICAgLy8gaW5pdGlhbGl6aW5nIHRoZSByZWFycmFuZ2VkIGFjY2VudCBhcnJheQoJICAgICAgICBpZiAoaGFzUGF0dGVybkFjY2VudHMgJiYgIWZvdW5kKSB7CgkgICAgICAgICAgICBmb3VuZCA9IGRvTmV4dENhbm9uaWNhbE1hdGNoKHRleHRvZmZzZXQpOwoJICAgICAgICB9CgkKCSAgICAgICAgaWYgKCFmb3VuZCkgewoJICAgICAgICAgICAgdGV4dG9mZnNldCA9IHNoaWZ0Rm9yd2FyZCh0ZXh0b2Zmc2V0LCB0YXJnZXRjZSwgcGF0dGVybmNlaW5kZXgpOwoJICAgICAgICAgICAgLy8gc3RhdHVzIGNoZWNrZWQgYXQgbG9vcAoJICAgICAgICAgICAgcGF0dGVybmNlaW5kZXggPSBtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfOwoJICAgICAgICAgICAgY29udGludWU7CgkgICAgICAgIH0KCSAgICAgICAgCgkgICAgICAgIGlmIChjaGVja05leHRDYW5vbmljYWxNYXRjaCh0ZXh0b2Zmc2V0KSkgewoJICAgICAgICAgICAgcmV0dXJuOwoJICAgICAgICB9CgkgICAgICAgIHRleHRvZmZzZXQgPSBtX3V0aWxCdWZmZXJfWzBdOwoJICAgIH0KCSAgICBzZXRNYXRjaE5vdEZvdW5kKCk7Cgl9CgkKCS8qKgoJICogTWV0aG9kIHRoYXQgZG9lcyB0aGUgcHJldmlvdXMgZXhhY3QgbWF0Y2gKCSAqIEBwYXJhbSBzdGFydCB0aGUgb2Zmc2V0IHRvIHN0YXJ0IHNoaWZ0aW5nIGZyb20gYW5kIHBlcmZvcm1pbmcgdGhlIAoJICogICAgICAgIHByZXZpb3VzIGV4YWN0IG1hdGNoCgkgKi8KCXByaXZhdGUgdm9pZCBoYW5kbGVQcmV2aW91c0V4YWN0KGludCBzdGFydCkKCXsKCSAgICBpbnQgdGV4dG9mZnNldCA9IHJldmVyc2VTaGlmdChzdGFydCwgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUiwgCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyk7CgkgICAgd2hpbGUgKHRleHRvZmZzZXQgPj0gbV90ZXh0QmVnaW5PZmZzZXRfKQoJICAgIHsKCSAgICAJbV9jb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQodGV4dG9mZnNldCk7CgkgICAgICAgIGludCBwYXR0ZXJuY2VpbmRleCA9IDE7CgkgICAgICAgIGludCB0YXJnZXRjZSA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEU7CgkgICAgICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKCSAgICAgICAgaW50IGZpcnN0Y2UgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSOwoJICAgICAgICAKCSAgICAgICAgd2hpbGUgKHRydWUpIHsKCSAgICAgICAgICAgIC8vIGZpbmRpbmcgdGhlIGZpcnN0IHBhdHRlcm4gY2UgbWF0Y2gsIGltYWdpbmUgY29tcG9zaXRlIAoJICAgICAgICAgICAgLy8gY2hhcmFjdGVycy4gZm9yIGV4YW1wbGU6IHNlYXJjaCBmb3IgcGF0dGVybiBcdTAzMDAgaW4gdGV4dCAKCSAgICAgICAgICAgIC8vIFx1MDBDMCwgd2UnbGwgaGF2ZSB0byBza2lwIEEgZmlyc3QgYmVmb3JlIHdlIGdldCB0byAKCSAgICAgICAgICAgIC8vIFx1MDMwMCB0aGUgZ3JhdmUgYWNjZW50CgkgICAgICAgICAgICB0YXJnZXRjZSA9IG1fY29sRUl0ZXJfLm5leHQoKTsKCSAgICAgICAgICAgIGlmICh0YXJnZXRjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CgkgICAgICAgICAgICAgICAgZm91bmQgPSBmYWxzZTsKCSAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHRhcmdldGNlID0gZ2V0Q0UodGFyZ2V0Y2UpOwoJICAgICAgICAgICAgaWYgKGZpcnN0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUiAKCSAgICAgICAgICAgIAl8fCBmaXJzdGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgICAgICBmaXJzdGNlID0gdGFyZ2V0Y2U7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAodGFyZ2V0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLklHTk9SQUJMRSkgewoJICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICAgICAgfSAgICAgICAgIAoJICAgICAgICAgICAgaWYgKHRhcmdldGNlID09IG1fcGF0dGVybl8ubV9DRV9bMF0pIHsKCSAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CgkgICAgICAgICAgICAgICAgYnJlYWs7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAobV9jb2xFSXRlcl8ubV9DRUJ1ZmZlck9mZnNldF8gPT0gLTEgCgkgICAgICAgICAgICAJfHwgbV9jb2xFSXRlcl8ubV9DRUJ1ZmZlck9mZnNldF8gCgkgICAgICAgICAgICAJCQkJCQkJPT0gbV9jb2xFSXRlcl8ubV9DRUJ1ZmZlclNpemVfKSB7CgkgICAgICAgICAgICAgICAgLy8gY2hlY2tpbmcgZm9yIGFjY2VudHMgaW4gY29tcG9zaXRlIGNoYXJhY3RlcgoJICAgICAgICAgICAgICAgIGZvdW5kID0gZmFsc2U7CgkgICAgICAgICAgICAgICAgYnJlYWs7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCQoJICAgICAgICB0YXJnZXRjZSA9IGZpcnN0Y2U7CgkgICAgICAgIAoJICAgICAgICB3aGlsZSAoZm91bmQgJiYgcGF0dGVybmNlaW5kZXggPCBtX3BhdHRlcm5fLm1fQ0VMZW5ndGhfKSB7CgkgICAgICAgICAgICB0YXJnZXRjZSA9IG1fY29sRUl0ZXJfLm5leHQoKTsKCSAgICAgICAgICAgIGlmICh0YXJnZXRjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CgkgICAgICAgICAgICAgICAgZm91bmQgPSBmYWxzZTsKCSAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHRhcmdldGNlID0gZ2V0Q0UodGFyZ2V0Y2UpOwoJICAgICAgICAgICAgaWYgKHRhcmdldGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgICAgIH0KCQoJICAgICAgICAgICAgZm91bmQgPSBmb3VuZCAmJiB0YXJnZXRjZSA9PSBtX3BhdHRlcm5fLm1fQ0VfW3BhdHRlcm5jZWluZGV4XTsgCgkgICAgICAgICAgICBwYXR0ZXJuY2VpbmRleCArKzsKCSAgICAgICAgfQoJCgkgICAgICAgIGlmICghZm91bmQpIHsKCSAgICAgICAgICAgIHRleHRvZmZzZXQgPSByZXZlcnNlU2hpZnQodGV4dG9mZnNldCwgdGFyZ2V0Y2UsIHBhdHRlcm5jZWluZGV4KTsKCSAgICAgICAgICAgIHBhdHRlcm5jZWluZGV4ID0gMDsKCSAgICAgICAgICAgIGNvbnRpbnVlOwoJICAgICAgICB9CgkgICAgICAgIAoJICAgICAgICBpZiAoY2hlY2tQcmV2aW91c0V4YWN0TWF0Y2godGV4dG9mZnNldCkpIHsKCSAgICAgICAgICAgIHJldHVybjsKCSAgICAgICAgfQoJICAgICAgICB0ZXh0b2Zmc2V0ID0gbV91dGlsQnVmZmVyX1swXTsKCSAgICB9CgkgICAgc2V0TWF0Y2hOb3RGb3VuZCgpOwoJfQoJCgkvKioKCSAqIE1ldGhvZCB0aGF0IGRvZXMgdGhlIHByZXZpb3VzIGNhbm9uaWNhbCBtYXRjaAoJICogQHBhcmFtIHN0YXJ0IHRoZSBvZmZzZXQgdG8gc3RhcnQgc2hpZnRpbmcgZnJvbSBhbmQgcGVyZm9ybWluZyB0aGUgCgkgKiAgICAgICAgcHJldmlvdXMgY2Fub25pY2FsIG1hdGNoCgkgKi8KCXByaXZhdGUgdm9pZCBoYW5kbGVQcmV2aW91c0Nhbm9uaWNhbChpbnQgc3RhcnQpCgl7CgkgICAgYm9vbGVhbiBoYXNQYXR0ZXJuQWNjZW50cyA9IAoJICAgICAgIG1fcGF0dGVybl8ubV9oYXNTdWZmaXhBY2NlbnRzXyB8fCBtX3BhdHRlcm5fLm1faGFzUHJlZml4QWNjZW50c187CgkgICAgICAgICAgCgkgICAgLy8gc2hpZnRpbmcgaXQgY2hlY2sgZm9yIHNldHRpbmcgb2Zmc2V0CgkgICAgLy8gaWYgc2V0T2Zmc2V0IGlzIGNhbGxlZCBwcmV2aW91c2x5IG9yIHRoZXJlIHdhcyBubyBwcmV2aW91cyBtYXRjaCwgd2UKCSAgICAvLyBsZWF2ZSB0aGUgb2Zmc2V0IGFzIGl0IGlzLgoJICAgIGludCB0ZXh0b2Zmc2V0ID0gcmV2ZXJzZVNoaWZ0KHN0YXJ0LCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSLCAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAkJbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXyk7CgkgICAgbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5kZWxldGUoMCwgbV9jYW5vbmljYWxQcmVmaXhBY2NlbnRzXy5sZW5ndGgoKSk7CgkgICAgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5kZWxldGUoMCwgbV9jYW5vbmljYWxTdWZmaXhBY2NlbnRzXy5sZW5ndGgoKSk7CgkgICAgCgkgICAgd2hpbGUgKHRleHRvZmZzZXQgPj0gbV90ZXh0QmVnaW5PZmZzZXRfKQoJICAgIHsKCSAgICAJbV9jb2xFSXRlcl8uc2V0RXhhY3RPZmZzZXQodGV4dG9mZnNldCk7CgkgICAgICAgIGludCBwYXR0ZXJuY2VpbmRleCA9IDE7CgkgICAgICAgIGludCB0YXJnZXRjZSA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEU7CgkgICAgICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKCSAgICAgICAgaW50IGZpcnN0Y2UgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSOwoJICAgICAgICAKCSAgICAgICAgd2hpbGUgKHRydWUpIHsKCSAgICAgICAgICAgIC8vIGZpbmRpbmcgdGhlIGZpcnN0IHBhdHRlcm4gY2UgbWF0Y2gsIGltYWdpbmUgY29tcG9zaXRlIAoJICAgICAgICAgICAgLy8gY2hhcmFjdGVycy4gZm9yIGV4YW1wbGU6IHNlYXJjaCBmb3IgcGF0dGVybiBcdTAzMDAgaW4gdGV4dCAKCSAgICAgICAgICAgIC8vIFx1MDBDMCwgd2UnbGwgaGF2ZSB0byBza2lwIEEgZmlyc3QgYmVmb3JlIHdlIGdldCB0byAKCSAgICAgICAgICAgIC8vIFx1MDMwMCB0aGUgZ3JhdmUgYWNjZW50CgkgICAgICAgICAgICB0YXJnZXRjZSA9IG1fY29sRUl0ZXJfLm5leHQoKTsKCSAgICAgICAgICAgIGlmICh0YXJnZXRjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuTlVMTE9SREVSKSB7CgkgICAgICAgICAgICAgICAgZm91bmQgPSBmYWxzZTsKCSAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHRhcmdldGNlID0gZ2V0Q0UodGFyZ2V0Y2UpOwoJICAgICAgICAgICAgaWYgKGZpcnN0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUiAKCSAgICAgICAgICAgIAl8fCBmaXJzdGNlID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5JR05PUkFCTEUpIHsKCSAgICAgICAgICAgICAgICBmaXJzdGNlID0gdGFyZ2V0Y2U7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICAKCSAgICAgICAgICAgIGlmICh0YXJnZXRjZSA9PSBtX3BhdHRlcm5fLm1fQ0VfWzBdKSB7CgkgICAgICAgICAgICAgICAgLy8gdGhlIGZpcnN0IGNlIGNhbiBiZSBhIGNvbnRyYWN0aW9uCgkgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJPZmZzZXRfID09IC0xIAoJICAgICAgICAgICAgCXx8IG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJPZmZzZXRfIAoJICAgICAgICAgICAgCQkJCQkJCT09IG1fY29sRUl0ZXJfLm1fQ0VCdWZmZXJTaXplXykgewoJICAgICAgICAgICAgICAgIC8vIGNoZWNraW5nIGZvciBhY2NlbnRzIGluIGNvbXBvc2l0ZSBjaGFyYWN0ZXIKCSAgICAgICAgICAgICAgICBmb3VuZCA9IGZhbHNlOwoJICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkKCSAgICAgICAgdGFyZ2V0Y2UgPSBmaXJzdGNlOwoJICAgICAgICAKCSAgICAgICAgd2hpbGUgKGZvdW5kICYmIHBhdHRlcm5jZWluZGV4IDwgbV9wYXR0ZXJuXy5tX0NFTGVuZ3RoXykgewoJICAgICAgICAgICAgdGFyZ2V0Y2UgPSBtX2NvbEVJdGVyXy5uZXh0KCk7CgkgICAgICAgICAgICBpZiAodGFyZ2V0Y2UgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLk5VTExPUkRFUikgewoJICAgICAgICAgICAgICAgIGZvdW5kID0gZmFsc2U7CgkgICAgICAgICAgICAgICAgYnJlYWs7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICB0YXJnZXRjZSA9IGdldENFKHRhcmdldGNlKTsKCSAgICAgICAgICAgIGlmICh0YXJnZXRjZSA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuSUdOT1JBQkxFKSB7CgkgICAgICAgICAgICAgICAgY29udGludWU7CgkgICAgICAgICAgICB9CgkKCSAgICAgICAgICAgIGZvdW5kID0gZm91bmQgJiYgdGFyZ2V0Y2UgPT0gbV9wYXR0ZXJuXy5tX0NFX1twYXR0ZXJuY2VpbmRleF07IAoJICAgICAgICAgICAgcGF0dGVybmNlaW5kZXggKys7CgkgICAgICAgIH0KCQoJICAgICAgICAvLyBpbml0aWFsaXppbmcgdGhlIHJlYXJyYW5nZWQgYWNjZW50IGFycmF5CgkgICAgICAgIGlmIChoYXNQYXR0ZXJuQWNjZW50cyAmJiAhZm91bmQpIHsKCSAgICAgICAgICAgIGZvdW5kID0gZG9QcmV2aW91c0Nhbm9uaWNhbE1hdGNoKHRleHRvZmZzZXQpOwoJICAgICAgICB9CgkKCSAgICAgICAgaWYgKCFmb3VuZCkgewoJICAgICAgICAgICAgdGV4dG9mZnNldCA9IHJldmVyc2VTaGlmdCh0ZXh0b2Zmc2V0LCB0YXJnZXRjZSwgcGF0dGVybmNlaW5kZXgpOwoJICAgICAgICAgICAgcGF0dGVybmNlaW5kZXggPSAwOwoJICAgICAgICAgICAgY29udGludWU7CgkgICAgICAgIH0KCQoJICAgICAgICBpZiAoY2hlY2tQcmV2aW91c0Nhbm9uaWNhbE1hdGNoKHRleHRvZmZzZXQpKSB7CgkgICAgICAgICAgICByZXR1cm47CgkgICAgICAgIH0KCSAgICAgICAgdGV4dG9mZnNldCA9IG1fdXRpbEJ1ZmZlcl9bMF07CgkgICAgfQoJICAgIHNldE1hdGNoTm90Rm91bmQoKTsKCX0KCQoJLyoqCgkgKiBHZXRzIGEgc3Vic3RyaW5nIG91dCBvZiBhIENoYXJhY3Rlckl0ZXJhdG9yCgkgKiBAcGFyYW0gdGV4dCBDaGFyYWN0ZXJJdGVyYXRvcgoJICogQHBhcmFtIHN0YXJ0IHN0YXJ0IG9mZnNldAoJICogQHBhcmFtIGxlbmd0aCBvZiBzdWJzdHJpbmcKCSAqIEByZXR1cm4gc3Vic3RyaW5nIGZyb20gdGV4dCBzdGFydGluZyBhdCBzdGFydCBhbmQgbGVuZ3RoIGxlbmd0aAoJICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgZ2V0U3RyaW5nKENoYXJhY3Rlckl0ZXJhdG9yIHRleHQsIGludCBzdGFydCwKCQkJCQkJCQkJCQlpbnQgbGVuZ3RoKQoJewoJCVN0cmluZ0J1ZmZlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVmZmVyKGxlbmd0aCk7CgkJaW50IG9mZnNldCA9IHRleHQuZ2V0SW5kZXgoKTsKCQl0ZXh0LnNldEluZGV4KHN0YXJ0KTsKCQlmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSArKykgewoJCQlyZXN1bHQuYXBwZW5kKHRleHQuY3VycmVudCgpKTsKCQkJdGV4dC5uZXh0KCk7CgkJfQoJCXRleHQuc2V0SW5kZXgob2Zmc2V0KTsKCQlyZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7Cgl9CgkKCS8qKgoJICogR2V0dGluZyB0aGUgbWFzayBmb3IgY29sbGF0aW9uIHN0cmVuZ3RoCgkgKiBAcGFyYW0gc3RyZW5ndGggY29sbGF0aW9uIHN0cmVuZ3RoCiAJICogQHJldHVybiBjb2xsYXRpb24gZWxlbWVudCBtYXNrCgkgKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBnZXRNYXNrKGludCBzdHJlbmd0aCkgCgl7CgkgICAgc3dpdGNoIChzdHJlbmd0aCkgCgkgICAgewoJICAgIAljYXNlIENvbGxhdG9yLlBSSU1BUlk6CgkgICAgICAgIAlyZXR1cm4gUnVsZUJhc2VkQ29sbGF0b3IuQ0VfUFJJTUFSWV9NQVNLXzsKCSAgICAJY2FzZSBDb2xsYXRvci5TRUNPTkRBUlk6CgkgICAgICAgIAlyZXR1cm4gUnVsZUJhc2VkQ29sbGF0b3IuQ0VfU0VDT05EQVJZX01BU0tfIAoJICAgICAgICAJICAgICAgIHwgUnVsZUJhc2VkQ29sbGF0b3IuQ0VfUFJJTUFSWV9NQVNLXzsKCSAgICAJZGVmYXVsdDoKCSAgICAgICAgCXJldHVybiBSdWxlQmFzZWRDb2xsYXRvci5DRV9URVJUSUFSWV9NQVNLXyAKCSAgICAgICAgCSAgICAgICB8IFJ1bGVCYXNlZENvbGxhdG9yLkNFX1NFQ09OREFSWV9NQVNLXyAKCSAgICAgICAgICAgICAgICAgICB8IFJ1bGVCYXNlZENvbGxhdG9yLkNFX1BSSU1BUllfTUFTS187CgkgICAgfQoJfQogICAgCiAgICAvKioKICAgICAqIFNldHMgbWF0Y2ggbm90IGZvdW5kIAogICAgICovCiAgICBwcml2YXRlIHZvaWQgc2V0TWF0Y2hOb3RGb3VuZCgpIAogICAgewogICAgICAgIC8vIHRoaXMgbWV0aG9kIHJlc2V0cyB0aGUgbWF0Y2ggcmVzdWx0IHJlZ2FyZGxlc3Mgb2YgdGhlIGVycm9yIHN0YXR1cy4KICAgICAgICBtX21hdGNoZWRJbmRleF8gPSBET05FOwogICAgICAgIHNldE1hdGNoTGVuZ3RoKDApOwogICAgfQp9Cg==