text:
/**
 * @module ol/render/canvas/ExecutorGroup
 */

import BuilderType from './BuilderType.js';
import Executor from './Executor.js';
import {buffer, createEmpty, extendCoordinate} from '../../extent.js';
import {
  compose as composeTransform,
  create as createTransform,
} from '../../transform.js';
import {createCanvasContext2D} from '../../dom.js';
import {isEmpty} from '../../obj.js';
import {numberSafeCompareFunction} from '../../array.js';
import {transform2D} from '../../geom/flat/transform.js';

/**
 * @const
 * @type {Array<import("./BuilderType.js").default>}
 */
const ORDER = [
  BuilderType.POLYGON,
  BuilderType.CIRCLE,
  BuilderType.LINE_STRING,
  BuilderType.IMAGE,
  BuilderType.TEXT,
  BuilderType.DEFAULT,
];

class ExecutorGroup {
  /**
   * @param {import("../../extent.js").Extent} maxExtent Max extent for clipping. When a
   * `maxExtent` was set on the Builder for this executor group, the same `maxExtent`
   * should be set here, unless the target context does not exceed that extent (which
   * can be the case when rendering to tiles).
   * @param {number} resolution Resolution.
   * @param {number} pixelRatio Pixel ratio.
   * @param {boolean} overlaps The executor group can have overlapping geometries.
   * @param {!Object<string, !Object<import("./BuilderType.js").default, import("../canvas.js").SerializableInstructions>>} allInstructions
   * The serializable instructions.
   * @param {number} [opt_renderBuffer] Optional rendering buffer.
   */
  constructor(
    maxExtent,
    resolution,
    pixelRatio,
    overlaps,
    allInstructions,
    opt_renderBuffer
  ) {
    /**
     * @private
     * @type {import("../../extent.js").Extent}
     */
    this.maxExtent_ = maxExtent;

    /**
     * @private
     * @type {boolean}
     */
    this.overlaps_ = overlaps;

    /**
     * @private
     * @type {number}
     */
    this.pixelRatio_ = pixelRatio;

    /**
     * @private
     * @type {number}
     */
    this.resolution_ = resolution;

    /**
     * @private
     * @type {number|undefined}
     */
    this.renderBuffer_ = opt_renderBuffer;

    /**
     * @private
     * @type {!Object<string, !Object<import("./BuilderType.js").default, import("./Executor").default>>}
     */
    this.executorsByZIndex_ = {};

    /**
     * @private
     * @type {CanvasRenderingContext2D}
     */
    this.hitDetectionContext_ = null;

    /**
     * @private
     * @type {import("../../transform.js").Transform}
     */
    this.hitDetectionTransform_ = createTransform();

    this.createExecutors_(allInstructions);
  }

  /**
   * @param {CanvasRenderingContext2D} context Context.
   * @param {import("../../transform.js").Transform} transform Transform.
   */
  clip(context, transform) {
    const flatClipCoords = this.getClipCoords(transform);
    context.beginPath();
    context.moveTo(flatClipCoords[0], flatClipCoords[1]);
    context.lineTo(flatClipCoords[2], flatClipCoords[3]);
    context.lineTo(flatClipCoords[4], flatClipCoords[5]);
    context.lineTo(flatClipCoords[6], flatClipCoords[7]);
    context.clip();
  }

  /**
   * Create executors and populate them using the provided instructions.
   * @private
   * @param {!Object<string, !Object<import("./BuilderType.js").default, import("../canvas.js").SerializableInstructions>>} allInstructions The serializable instructions
   */
  createExecutors_(allInstructions) {
    for (const zIndex in allInstructions) {
      let executors = this.executorsByZIndex_[zIndex];
      if (executors === undefined) {
        executors = {};
        this.executorsByZIndex_[zIndex] = executors;
      }
      const instructionByZindex = allInstructions[zIndex];
      for (const builderType in instructionByZindex) {
        const instructions = instructionByZindex[builderType];
        executors[builderType] = new Executor(
          this.resolution_,
          this.pixelRatio_,
          this.overlaps_,
          instructions
        );
      }
    }
  }

  /**
   * @param {Array<import("./BuilderType.js").default>} executors Executors.
   * @return {boolean} Has executors of the provided types.
   */
  hasExecutors(executors) {
    for (const zIndex in this.executorsByZIndex_) {
      const candidates = this.executorsByZIndex_[zIndex];
      for (let i = 0, ii = executors.length; i < ii; ++i) {
        if (executors[i] in candidates) {
          return true;
        }
      }
    }
    return false;
  }

  /**
   * @param {import("../../coordinate.js").Coordinate} coordinate Coordinate.
   * @param {number} resolution Resolution.
   * @param {number} rotation Rotation.
   * @param {number} hitTolerance Hit tolerance in pixels.
   * @param {function(import("../../Feature.js").FeatureLike, import("../../geom/SimpleGeometry.js").default, number): T} callback Feature callback.
   * @param {Array<import("../../Feature.js").FeatureLike>} declutteredFeatures Decluttered features.
   * @return {T|undefined} Callback result.
   * @template T
   */
  forEachFeatureAtCoordinate(
    coordinate,
    resolution,
    rotation,
    hitTolerance,
    callback,
    declutteredFeatures
  ) {
    hitTolerance = Math.round(hitTolerance);
    const contextSize = hitTolerance * 2 + 1;
    const transform = composeTransform(
      this.hitDetectionTransform_,
      hitTolerance + 0.5,
      hitTolerance + 0.5,
      1 / resolution,
      -1 / resolution,
      -rotation,
      -coordinate[0],
      -coordinate[1]
    );

    const newContext = !this.hitDetectionContext_;
    if (newContext) {
      this.hitDetectionContext_ = createCanvasContext2D(
        contextSize,
        contextSize
      );
    }
    const context = this.hitDetectionContext_;

    if (
      context.canvas.width !== contextSize ||
      context.canvas.height !== contextSize
    ) {
      context.canvas.width = contextSize;
      context.canvas.height = contextSize;
    } else if (!newContext) {
      context.clearRect(0, 0, contextSize, contextSize);
    }

    /**
     * @type {import("../../extent.js").Extent}
     */
    let hitExtent;
    if (this.renderBuffer_ !== undefined) {
      hitExtent = createEmpty();
      extendCoordinate(hitExtent, coordinate);
      buffer(
        hitExtent,
        resolution * (this.renderBuffer_ + hitTolerance),
        hitExtent
      );
    }

    const indexes = getPixelIndexArray(hitTolerance);

    let builderType;

    /**
     * @param {import("../../Feature.js").FeatureLike} feature Feature.
     * @param {import("../../geom/SimpleGeometry.js").default} geometry Geometry.
     * @return {T|undefined} Callback result.
     */
    function featureCallback(feature, geometry) {
      const imageData = context.getImageData(
        0,
        0,
        contextSize,
        contextSize
      ).data;
      for (let i = 0, ii = indexes.length; i < ii; i++) {
        if (imageData[indexes[i]] > 0) {
          if (
            !declutteredFeatures ||
            (builderType !== BuilderType.IMAGE &&
              builderType !== BuilderType.TEXT) ||
            declutteredFeatures.indexOf(feature) !== -1
          ) {
            const idx = (indexes[i] - 3) / 4;
            const x = hitTolerance - (idx % contextSize);
            const y = hitTolerance - ((idx / contextSize) | 0);
            const result = callback(feature, geometry, x * x + y * y);
            if (result) {
              return result;
            }
          }
          context.clearRect(0, 0, contextSize, contextSize);
          break;
        }
      }
      return undefined;
    }

    /** @type {Array<number>} */
    const zs = Object.keys(this.executorsByZIndex_).map(Number);
    zs.sort(numberSafeCompareFunction);

    let i, j, executors, executor, result;
    for (i = zs.length - 1; i >= 0; --i) {
      const zIndexKey = zs[i].toString();
      executors = this.executorsByZIndex_[zIndexKey];
      for (j = ORDER.length - 1; j >= 0; --j) {
        builderType = ORDER[j];
        executor = executors[builderType];
        if (executor !== undefined) {
          result = executor.executeHitDetection(
            context,
            transform,
            rotation,
            featureCallback,
            hitExtent
          );
          if (result) {
            return result;
          }
        }
      }
    }
    return undefined;
  }

  /**
   * @param {import("../../transform.js").Transform} transform Transform.
   * @return {Array<number>} Clip coordinates.
   */
  getClipCoords(transform) {
    const maxExtent = this.maxExtent_;
    if (!maxExtent) {
      return null;
    }
    const minX = maxExtent[0];
    const minY = maxExtent[1];
    const maxX = maxExtent[2];
    const maxY = maxExtent[3];
    const flatClipCoords = [minX, minY, minX, maxY, maxX, maxY, maxX, minY];
    transform2D(flatClipCoords, 0, 8, 2, transform, flatClipCoords);
    return flatClipCoords;
  }

  /**
   * @return {boolean} Is empty.
   */
  isEmpty() {
    return isEmpty(this.executorsByZIndex_);
  }

  /**
   * @param {CanvasRenderingContext2D} context Context.
   * @param {number} contextScale Scale of the context.
   * @param {import("../../transform.js").Transform} transform Transform.
   * @param {number} viewRotation View rotation.
   * @param {boolean} snapToPixel Snap point symbols and test to integer pixel.
   * @param {Array<import("./BuilderType.js").default>} [opt_builderTypes] Ordered replay types to replay.
   *     Default is {@link module:ol/render/replay~ORDER}
   * @param {import("rbush").default} [opt_declutterTree] Declutter tree.
   */
  execute(
    context,
    contextScale,
    transform,
    viewRotation,
    snapToPixel,
    opt_builderTypes,
    opt_declutterTree
  ) {
    /** @type {Array<number>} */
    const zs = Object.keys(this.executorsByZIndex_).map(Number);
    zs.sort(numberSafeCompareFunction);

    // setup clipping so that the parts of over-simplified geometries are not
    // visible outside the current extent when panning
    if (this.maxExtent_) {
      context.save();
      this.clip(context, transform);
    }

    const builderTypes = opt_builderTypes ? opt_builderTypes : ORDER;
    let i, ii, j, jj, replays, replay;
    if (opt_declutterTree) {
      zs.reverse();
    }
    for (i = 0, ii = zs.length; i < ii; ++i) {
      const zIndexKey = zs[i].toString();
      replays = this.executorsByZIndex_[zIndexKey];
      for (j = 0, jj = builderTypes.length; j < jj; ++j) {
        const builderType = builderTypes[j];
        replay = replays[builderType];
        if (replay !== undefined) {
          replay.execute(
            context,
            contextScale,
            transform,
            viewRotation,
            snapToPixel,
            opt_declutterTree
          );
        }
      }
    }

    if (this.maxExtent_) {
      context.restore();
    }
  }
}

/**
 * This cache is used to store arrays of indexes for calculated pixel circles
 * to increase performance.
 * It is a static property to allow each Replaygroup to access it.
 * @type {Object<number, Array<number>>}
 */
const circlePixelIndexArrayCache = {};

/**
 * This methods creates an array with indexes of all pixels within a circle,
 * ordered by how close they are to the center.
 * A cache is used to increase performance.
 * @param {number} radius Radius.
 * @return {Array<number>} An array with indexes within a circle.
 */
export function getPixelIndexArray(radius) {
  if (circlePixelIndexArrayCache[radius] !== undefined) {
    return circlePixelIndexArrayCache[radius];
  }

  const size = radius * 2 + 1;
  const maxDistanceSq = radius * radius;
  const distances = new Array(maxDistanceSq + 1);
  for (let i = 0; i <= radius; ++i) {
    for (let j = 0; j <= radius; ++j) {
      const distanceSq = i * i + j * j;
      if (distanceSq > maxDistanceSq) {
        break;
      }
      let distance = distances[distanceSq];
      if (!distance) {
        distance = [];
        distances[distanceSq] = distance;
      }
      distance.push(((radius + i) * size + (radius + j)) * 4 + 3);
      if (i > 0) {
        distance.push(((radius - i) * size + (radius + j)) * 4 + 3);
      }
      if (j > 0) {
        distance.push(((radius + i) * size + (radius - j)) * 4 + 3);
        if (i > 0) {
          distance.push(((radius - i) * size + (radius - j)) * 4 + 3);
        }
      }
    }
  }

  const pixelIndex = [];
  for (let i = 0, ii = distances.length; i < ii; ++i) {
    if (distances[i]) {
      pixelIndex.push(...distances[i]);
    }
  }

  circlePixelIndexArrayCache[radius] = pixelIndex;
  return pixelIndex;
}

export default ExecutorGroup;


text:
package mobi.porquenao.gol.rule;

import android.support.annotation.NonNull;

import mobi.porquenao.gol.Gol;

public class LimitRule implements Gol.Rule {

    private int mLimit;
    private int mLogged;

    public LimitRule(int limit) {
        mLimit = limit;
    }

    @Override
    public boolean isLoggable(int priority, @NonNull String tag) {
        return mLogged++ < mLimit;
    }

}

redpajama_set_name: RedPajamaGithub


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AppStudio.Uwp.Html
{
    public class HtmlException : Exception
    {
        public HtmlException()
        {
        }

        public HtmlException(string message) : base(message)
        {
        }

        public HtmlException(string message, Exception innerException) : base(message, innerException)
        {
        }
    }
}


text:
package apple.webkit;

import apple.NSObject;
import apple.coregraphics.struct.CGRect;
import apple.foundation.NSArray;
import apple.foundation.NSCoder;
import apple.foundation.NSData;
import apple.foundation.NSDate;
import apple.foundation.NSDictionary;
import apple.foundation.NSError;
import apple.foundation.NSMethodSignature;
import apple.foundation.NSSet;
import apple.foundation.NSURL;
import apple.foundation.NSURLRequest;
import apple.foundation.NSURLResponse;
import apple.security.opaque.SecTrustRef;
import apple.uikit.UIColor;
import apple.uikit.UIImage;
import apple.uikit.UIScrollView;
import apple.uikit.UITraitCollection;
import apple.uikit.UIView;
import apple.uikit.protocol.UIAppearanceContainer;
import apple.webkit.protocol.WKNavigationDelegate;
import apple.webkit.protocol.WKUIDelegate;
import org.moe.natj.c.ann.FunctionPtr;
import org.moe.natj.c.ann.Variadic;
import org.moe.natj.general.NatJ;
import org.moe.natj.general.Pointer;
import org.moe.natj.general.ann.ByValue;
import org.moe.natj.general.ann.Generated;
import org.moe.natj.general.ann.Library;
import org.moe.natj.general.ann.Mapped;
import org.moe.natj.general.ann.MappedReturn;
import org.moe.natj.general.ann.NFloat;
import org.moe.natj.general.ann.NInt;
import org.moe.natj.general.ann.NUInt;
import org.moe.natj.general.ann.Owned;
import org.moe.natj.general.ann.Runtime;
import org.moe.natj.general.ptr.VoidPtr;
import org.moe.natj.objc.Class;
import org.moe.natj.objc.ObjCRuntime;
import org.moe.natj.objc.SEL;
import org.moe.natj.objc.ann.ObjCBlock;
import org.moe.natj.objc.ann.ObjCClassBinding;
import org.moe.natj.objc.ann.ProtocolClassMethod;
import org.moe.natj.objc.ann.Selector;
import org.moe.natj.objc.map.ObjCObjectMapper;

@Generated
@Library("WebKit")
@Runtime(ObjCRuntime.class)
@ObjCClassBinding
public class WKWebView extends UIView {
    static {
        NatJ.register();
    }

    @Generated
    protected WKWebView(Pointer peer) {
        super(peer);
    }

    @Generated
    @Selector("accessInstanceVariablesDirectly")
    public static native boolean accessInstanceVariablesDirectly();

    @Generated
    @Selector("addKeyframeWithRelativeStartTime:relativeDuration:animations:")
    public static native void addKeyframeWithRelativeStartTimeRelativeDurationAnimations(double frameStartTime,
            double frameDuration,
            @ObjCBlock(name = "call_addKeyframeWithRelativeStartTimeRelativeDurationAnimations") UIView.Block_addKeyframeWithRelativeStartTimeRelativeDurationAnimations animations);

    @Generated
    @Owned
    @Selector("alloc")
    public static native WKWebView alloc();

    @Owned
    @Generated
    @Selector("allocWithZone:")
    public static native WKWebView allocWithZone(VoidPtr zone);

    @Generated
    @Selector("animateKeyframesWithDuration:delay:options:animations:completion:")
    public static native void animateKeyframesWithDurationDelayOptionsAnimationsCompletion(double duration,
            double delay, @NUInt long options,
            @ObjCBlock(name = "call_animateKeyframesWithDurationDelayOptionsAnimationsCompletion_3") UIView.Block_animateKeyframesWithDurationDelayOptionsAnimationsCompletion_3 animations,
            @ObjCBlock(name = "call_animateKeyframesWithDurationDelayOptionsAnimationsCompletion_4") UIView.Block_animateKeyframesWithDurationDelayOptionsAnimationsCompletion_4 completion);

    @Generated
    @Selector("animateWithDuration:animations:")
    public static native void animateWithDurationAnimations(double duration,
            @ObjCBlock(name = "call_animateWithDurationAnimations") UIView.Block_animateWithDurationAnimations animations);

    @Generated
    @Selector("animateWithDuration:animations:completion:")
    public static native void animateWithDurationAnimationsCompletion(double duration,
            @ObjCBlock(name = "call_animateWithDurationAnimationsCompletion_1") UIView.Block_animateWithDurationAnimationsCompletion_1 animations,
            @ObjCBlock(name = "call_animateWithDurationAnimationsCompletion_2") UIView.Block_animateWithDurationAnimationsCompletion_2 completion);

    @Generated
    @Selector("animateWithDuration:delay:options:animations:completion:")
    public static native void animateWithDurationDelayOptionsAnimationsCompletion(double duration, double delay,
            @NUInt long options,
            @ObjCBlock(name = "call_animateWithDurationDelayOptionsAnimationsCompletion_3") UIView.Block_animateWithDurationDelayOptionsAnimationsCompletion_3 animations,
            @ObjCBlock(name = "call_animateWithDurationDelayOptionsAnimationsCompletion_4") UIView.Block_animateWithDurationDelayOptionsAnimationsCompletion_4 completion);

    @Generated
    @Selector("animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:")
    public static native void animateWithDurationDelayUsingSpringWithDampingInitialSpringVelocityOptionsAnimationsCompletion(
            double duration, double delay, @NFloat double dampingRatio, @NFloat double velocity, @NUInt long options,
            @ObjCBlock(name = "call_animateWithDurationDelayUsingSpringWithDampingInitialSpringVelocityOptionsAnimationsCompletion_5") UIView.Block_animateWithDurationDelayUsingSpringWithDampingInitialSpringVelocityOptionsAnimationsCompletion_5 animations,
            @ObjCBlock(name = "call_animateWithDurationDelayUsingSpringWithDampingInitialSpringVelocityOptionsAnimationsCompletion_6") UIView.Block_animateWithDurationDelayUsingSpringWithDampingInitialSpringVelocityOptionsAnimationsCompletion_6 completion);

    @Generated
    @Selector("appearance")
    public static native WKWebView appearance();

    @Generated
    @Selector("appearanceForTraitCollection:")
    public static native WKWebView appearanceForTraitCollection(UITraitCollection trait);

    @Generated
    @Variadic()
    @Deprecated
    @Selector("appearanceForTraitCollection:whenContainedIn:")
    public static native WKWebView appearanceForTraitCollectionWhenContainedIn(UITraitCollection trait,
            @Mapped(ObjCObjectMapper.class) UIAppearanceContainer ContainerClass, Object... varargs);

    @Generated
    @Selector("appearanceForTraitCollection:whenContainedInInstancesOfClasses:")
    public static native WKWebView appearanceForTraitCollectionWhenContainedInInstancesOfClasses(
            UITraitCollection trait, NSArray<?> containerTypes);

    @Generated
    @Variadic()
    @Deprecated
    @Selector("appearanceWhenContainedIn:")
    public static native WKWebView appearanceWhenContainedIn(
            @Mapped(ObjCObjectMapper.class) UIAppearanceContainer ContainerClass, Object... varargs);

    @Generated
    @Selector("appearanceWhenContainedInInstancesOfClasses:")
    public static native WKWebView appearanceWhenContainedInInstancesOfClasses(NSArray<?> containerTypes);

    @Generated
    @Selector("areAnimationsEnabled")
    public static native boolean areAnimationsEnabled();

    @Generated
    @Selector("automaticallyNotifiesObserversForKey:")
    public static native boolean automaticallyNotifiesObserversForKey(String key);

    @Generated
    @Selector("beginAnimations:context:")
    public static native void beginAnimationsContext(String animationID, VoidPtr context);

    @Generated
    @Selector("cancelPreviousPerformRequestsWithTarget:")
    public static native void cancelPreviousPerformRequestsWithTarget(@Mapped(ObjCObjectMapper.class) Object aTarget);

    @Generated
    @Selector("cancelPreviousPerformRequestsWithTarget:selector:object:")
    public static native void cancelPreviousPerformRequestsWithTargetSelectorObject(
            @Mapped(ObjCObjectMapper.class) Object aTarget, SEL aSelector,
            @Mapped(ObjCObjectMapper.class) Object anArgument);

    @Generated
    @Selector("classFallbacksForKeyedArchiver")
    public static native NSArray<String> classFallbacksForKeyedArchiver();

    @Generated
    @Selector("classForKeyedUnarchiver")
    public static native Class classForKeyedUnarchiver();

    @Generated
    @Selector("clearTextInputContextIdentifier:")
    public static native void clearTextInputContextIdentifier(String identifier);

    @Generated
    @Selector("commitAnimations")
    public static native void commitAnimations();

    @Generated
    @Selector("debugDescription")
    public static native String debugDescription_static();

    @Generated
    @Selector("description")
    public static native String description_static();

    @Generated
    @Selector("hash")
    @NUInt
    public static native long hash_static();

    @Generated
    @Selector("inheritedAnimationDuration")
    public static native double inheritedAnimationDuration();

    @Generated
    @Selector("instanceMethodForSelector:")
    @FunctionPtr(name = "call_instanceMethodForSelector_ret")
    public static native NSObject.Function_instanceMethodForSelector_ret instanceMethodForSelector(SEL aSelector);

    @Generated
    @Selector("instanceMethodSignatureForSelector:")
    public static native NSMethodSignature instanceMethodSignatureForSelector(SEL aSelector);

    @Generated
    @Selector("instancesRespondToSelector:")
    public static native boolean instancesRespondToSelector(SEL aSelector);

    @Generated
    @Selector("isSubclassOfClass:")
    public static native boolean isSubclassOfClass(Class aClass);

    @Generated
    @Selector("keyPathsForValuesAffectingValueForKey:")
    public static native NSSet<String> keyPathsForValuesAffectingValueForKey(String key);

    @Generated
    @Selector("layerClass")
    public static native Class layerClass();

    @Generated
    @Owned
    @Selector("new")
    public static native WKWebView new_objc();

    @Generated
    @Selector("performSystemAnimation:onViews:options:animations:completion:")
    public static native void performSystemAnimationOnViewsOptionsAnimationsCompletion(@NUInt long animation,
            NSArray<? extends UIView> views, @NUInt long options,
            @ObjCBlock(name = "call_performSystemAnimationOnViewsOptionsAnimationsCompletion_3") UIView.Block_performSystemAnimationOnViewsOptionsAnimationsCompletion_3 parallelAnimations,
            @ObjCBlock(name = "call_performSystemAnimationOnViewsOptionsAnimationsCompletion_4") UIView.Block_performSystemAnimationOnViewsOptionsAnimationsCompletion_4 completion);

    @Generated
    @Selector("performWithoutAnimation:")
    public static native void performWithoutAnimation(
            @ObjCBlock(name = "call_performWithoutAnimation") UIView.Block_performWithoutAnimation actionsWithoutAnimation);

    @Generated
    @Selector("requiresConstraintBasedLayout")
    public static native boolean requiresConstraintBasedLayout();

    @Generated
    @Selector("resolveClassMethod:")
    public static native boolean resolveClassMethod(SEL sel);

    @Generated
    @Selector("resolveInstanceMethod:")
    public static native boolean resolveInstanceMethod(SEL sel);

    @Generated
    @Selector("setAnimationBeginsFromCurrentState:")
    public static native void setAnimationBeginsFromCurrentState(boolean fromCurrentState);

    @Generated
    @Selector("setAnimationCurve:")
    public static native void setAnimationCurve(@NInt long curve);

    @Generated
    @Selector("setAnimationDelay:")
    public static native void setAnimationDelay(double delay);

    @Generated
    @Selector("setAnimationDelegate:")
    public static native void setAnimationDelegate(@Mapped(ObjCObjectMapper.class) Object delegate);

    @Generated
    @Selector("setAnimationDidStopSelector:")
    public static native void setAnimationDidStopSelector(SEL selector);

    @Generated
    @Selector("setAnimationDuration:")
    public static native void setAnimationDuration_static(double duration);

    @Generated
    @Selector("setAnimationRepeatAutoreverses:")
    public static native void setAnimationRepeatAutoreverses(boolean repeatAutoreverses);

    @Generated
    @Selector("setAnimationRepeatCount:")
    public static native void setAnimationRepeatCount_static(float repeatCount);

    @Generated
    @Selector("setAnimationStartDate:")
    public static native void setAnimationStartDate(NSDate startDate);

    @Generated
    @Selector("setAnimationTransition:forView:cache:")
    public static native void setAnimationTransitionForViewCache(@NInt long transition, UIView view, boolean cache);

    @Generated
    @Selector("setAnimationWillStartSelector:")
    public static native void setAnimationWillStartSelector(SEL selector);

    @Generated
    @Selector("setAnimationsEnabled:")
    public static native void setAnimationsEnabled(boolean enabled);

    @Generated
    @Selector("setVersion:")
    public static native void setVersion_static(@NInt long aVersion);

    @Generated
    @Selector("superclass")
    public static native Class superclass_static();

    @Generated
    @Selector("transitionFromView:toView:duration:options:completion:")
    public static native void transitionFromViewToViewDurationOptionsCompletion(UIView fromView, UIView toView,
            double duration, @NUInt long options,
            @ObjCBlock(name = "call_transitionFromViewToViewDurationOptionsCompletion") UIView.Block_transitionFromViewToViewDurationOptionsCompletion completion);

    @Generated
    @Selector("transitionWithView:duration:options:animations:completion:")
    public static native void transitionWithViewDurationOptionsAnimationsCompletion(UIView view, double duration,
            @NUInt long options,
            @ObjCBlock(name = "call_transitionWithViewDurationOptionsAnimationsCompletion_3") UIView.Block_transitionWithViewDurationOptionsAnimationsCompletion_3 animations,
            @ObjCBlock(name = "call_transitionWithViewDurationOptionsAnimationsCompletion_4") UIView.Block_transitionWithViewDurationOptionsAnimationsCompletion_4 completion);

    @Generated
    @Selector("userInterfaceLayoutDirectionForSemanticContentAttribute:")
    @NInt
    public static native long userInterfaceLayoutDirectionForSemanticContentAttribute(@NInt long attribute);

    @Generated
    @Selector("userInterfaceLayoutDirectionForSemanticContentAttribute:relativeToLayoutDirection:")
    @NInt
    public static native long userInterfaceLayoutDirectionForSemanticContentAttributeRelativeToLayoutDirection(
            @NInt long semanticContentAttribute, @NInt long layoutDirection);

    @Generated
    @Selector("version")
    @NInt
    public static native long version_static();

    /**
     * The web view's user interface delegate.
     */
    @Generated
    @Selector("UIDelegate")
    @MappedReturn(ObjCObjectMapper.class)
    public native WKUIDelegate UIDelegate();

    /**
     * The active URL.
     *

     * This is the URL that should be reflected in the user
     * interface.
     * [@link] WKWebView @/link is key-value observing (KVO) compliant for this
     * property.
     */
    @Generated
    @Selector("URL")
    public native NSURL URL();

    /**
     * A Boolean value indicating whether horizontal swipe gestures
     * will trigger back-forward list navigations.
     *

     * The default value is NO.
     */
    @Generated
    @Selector("allowsBackForwardNavigationGestures")
    public native boolean allowsBackForwardNavigationGestures();

    /**
     * A Boolean value indicating whether link preview is allowed for any
     * links inside this WKWebView.
     *

     * The default value is YES on Mac and iOS.
     */
    @Generated
    @Selector("allowsLinkPreview")
    public native boolean allowsLinkPreview();

    @Generated
    @ProtocolClassMethod("appearance")
    public WKWebView _appearance() {
        return appearance();
    }

    @Generated
    @ProtocolClassMethod("appearanceForTraitCollection")
    public WKWebView _appearanceForTraitCollection(UITraitCollection trait) {
        return appearanceForTraitCollection(trait);
    }

    @Generated
    @Deprecated
    @ProtocolClassMethod("appearanceForTraitCollectionWhenContainedIn")
    public WKWebView _appearanceForTraitCollectionWhenContainedIn(UITraitCollection trait,
            @Mapped(ObjCObjectMapper.class) UIAppearanceContainer ContainerClass, Object... varargs) {
        return appearanceForTraitCollectionWhenContainedIn(trait, ContainerClass, varargs);
    }

    @Generated
    @ProtocolClassMethod("appearanceForTraitCollectionWhenContainedInInstancesOfClasses")
    public WKWebView _appearanceForTraitCollectionWhenContainedInInstancesOfClasses(UITraitCollection trait,
            NSArray<?> containerTypes) {
        return appearanceForTraitCollectionWhenContainedInInstancesOfClasses(trait, containerTypes);
    }

    @Generated
    @Deprecated
    @ProtocolClassMethod("appearanceWhenContainedIn")
    public WKWebView _appearanceWhenContainedIn(@Mapped(ObjCObjectMapper.class) UIAppearanceContainer ContainerClass,
            Object... varargs) {
        return appearanceWhenContainedIn(ContainerClass, varargs);
    }

    @Generated
    @ProtocolClassMethod("appearanceWhenContainedInInstancesOfClasses")
    public WKWebView _appearanceWhenContainedInInstancesOfClasses(NSArray<?> containerTypes) {
        return appearanceWhenContainedInInstancesOfClasses(containerTypes);
    }

    /**
     * The web view's back-forward list.
     */
    @Generated
    @Selector("backForwardList")
    public native WKBackForwardList backForwardList();

    /**
     * A Boolean value indicating whether there is a back item in
     * the back-forward list that can be navigated to.
     *

     * [@link] WKWebView @/link is key-value observing (KVO) compliant
     * for this property.
     *
     * @see backForwardList.
     */
    @Generated
    @Selector("canGoBack")
    public native boolean canGoBack();

    /**
     * A Boolean value indicating whether there is a forward item in
     * the back-forward list that can be navigated to.
     *

     * [@link] WKWebView @/link is key-value observing (KVO) compliant
     * for this property.
     *
     * @see backForwardList.
     */
    @Generated
    @Selector("canGoForward")
    public native boolean canGoForward();

    @Generated
    @Selector("certificateChain")
    public native NSArray<?> certificateChain();

    /**
     * A copy of the configuration with which the web view was
     * initialized.
     */
    @Generated
    @Selector("configuration")
    public native WKWebViewConfiguration configuration();

    /**
     * The custom user agent string or nil if no custom user agent string has been set.
     */
    @Generated
    @Selector("customUserAgent")
    public native String customUserAgent();

    /**
     * An estimate of what fraction of the current navigation has been completed.
     *

     * This value ranges from 0.0 to 1.0 based on the total number of
     * bytes expected to be received, including the main document and all of its
     * potential subresources. After a navigation completes, the value remains at 1.0
     * until a new navigation starts, at which point it is reset to 0.0.
     * [@link] WKWebView @/link is key-value observing (KVO) compliant for this
     * property.
     */
    @Generated
    @Selector("estimatedProgress")
    public native double estimatedProgress();

    /**
     * Evaluates the given JavaScript string.
     *

     * The completionHandler is passed the result of the script evaluation or an error.
     * Calling this method is equivalent to calling `evaluateJavaScript:inFrame:inContentWorld:completionHandler:` with:
     * - A `frame` value of `nil` to represent the main frame
     * - A `contentWorld` value of `WKContentWorld.pageWorld`
     *
     * @param javaScriptString  The JavaScript string to evaluate.
     * @param completionHandler A block to invoke when script evaluation completes or fails.
     */
    @Generated
    @Selector("evaluateJavaScript:completionHandler:")
    public native void evaluateJavaScriptCompletionHandler(String javaScriptString,
            @ObjCBlock(name = "call_evaluateJavaScriptCompletionHandler") Block_evaluateJavaScriptCompletionHandler completionHandler);

    /**
     * Navigates to the back item in the back-forward list.
     *
     * @return A new navigation to the requested item, or nil if there is no back
     *         item in the back-forward list.
     */
    @Generated
    @Selector("goBack")
    public native WKNavigation goBack();

    /**
     * Navigates to the forward item in the back-forward list.
     *
     * @return A new navigation to the requested item, or nil if there is no
     *         forward item in the back-forward list.
     */
    @Generated
    @Selector("goForward")
    public native WKNavigation goForward();

    /**
     * Navigates to an item from the back-forward list and sets it
     * as the current item.
     *
     * @param item The item to which to navigate. Must be one of the items in the
     *             web view's back-forward list.
     * @return A new navigation to the requested item, or nil if it is already
     *         the current item or is not part of the web view's back-forward list.
     * @see backForwardList
     */
    @Generated
    @Selector("goToBackForwardListItem:")
    public native WKNavigation goToBackForwardListItem(WKBackForwardListItem item);

    /**
     * A Boolean value indicating whether all resources on the page
     * have been loaded over securely encrypted connections.
     *

     * [@link] WKWebView @/link is key-value observing (KVO) compliant
     * for this property.
     */
    @Generated
    @Selector("hasOnlySecureContent")
    public native boolean hasOnlySecureContent();

    @Generated
    @Selector("init")
    public native WKWebView init();

    @Generated
    @Selector("initWithCoder:")
    public native WKWebView initWithCoder(NSCoder coder);

    @Generated
    @Selector("initWithFrame:")
    public native WKWebView initWithFrame(@ByValue CGRect frame);

    /**
     * Returns a web view initialized with a specified frame and
     * configuration.
     *

     * This is a designated initializer. You can use
     * [@link] -initWithFrame: @/link to initialize an instance with the default
     * configuration. The initializer copies the specified configuration, so
     * mutating the configuration after invoking the initializer has no effect
     * on the web view.
     *
     * @param frame         The frame for the new web view.
     * @param configuration The configuration for the new web view.
     * @return An initialized web view, or nil if the object could not be
     *         initialized.
     */
    @Generated
    @Selector("initWithFrame:configuration:")
    public native WKWebView initWithFrameConfiguration(@ByValue CGRect frame, WKWebViewConfiguration configuration);

    /**
     * A Boolean value indicating whether the view is currently
     * loading content.
     *

     * [@link] WKWebView @/link is key-value observing (KVO) compliant
     * for this property.
     */
    @Generated
    @Selector("isLoading")
    public native boolean isLoading();

    /**
     * Sets the webpage contents and base URL.
     *
     * @param data                  The data to use as the contents of the webpage.
     * @param MIMEType              The MIME type of the data.
     * @param characterEncodingName The data's character encoding name.
     * @param baseURL               A URL that is used to resolve relative URLs within the document.
     * @return A new navigation.
     */
    @Generated
    @Selector("loadData:MIMEType:characterEncodingName:baseURL:")
    public native WKNavigation loadDataMIMETypeCharacterEncodingNameBaseURL(NSData data, String MIMEType,
            String characterEncodingName, NSURL baseURL);

    /**
     * Navigates to the requested file URL on the filesystem.
     *

     * If readAccessURL references a single file, only that file may be loaded by WebKit.
     * If readAccessURL references a directory, files inside that file may be loaded by WebKit.
     *
     * @param URL           The file URL to which to navigate.
     * @param readAccessURL The URL to allow read access to.
     * @return A new navigation for the given file URL.
     */
    @Generated
    @Selector("loadFileURL:allowingReadAccessToURL:")
    public native WKNavigation loadFileURLAllowingReadAccessToURL(NSURL URL, NSURL readAccessURL);

    /**
     * Sets the webpage contents and base URL.
     *
     * @param string  The string to use as the contents of the webpage.
     * @param baseURL A URL that is used to resolve relative URLs within the document.
     * @return A new navigation.
     */
    @Generated
    @Selector("loadHTMLString:baseURL:")
    public native WKNavigation loadHTMLStringBaseURL(String string, NSURL baseURL);

    /**
     * Navigates to a requested URL.
     *
     * @param request The request specifying the URL to which to navigate.
     * @return A new navigation for the given request.
     */
    @Generated
    @Selector("loadRequest:")
    public native WKNavigation loadRequest(NSURLRequest request);

    /**
     * The web view's navigation delegate.
     */
    @Generated
    @Selector("navigationDelegate")
    @MappedReturn(ObjCObjectMapper.class)
    public native WKNavigationDelegate navigationDelegate();

    /**
     * Reloads the current page.
     *
     * @return A new navigation representing the reload.
     */
    @Generated
    @Selector("reload")
    public native WKNavigation reload();

    /**
     * Reloads the current page, performing end-to-end revalidation
     * using cache-validating conditionals if possible.
     *
     * @return A new navigation representing the reload.
     */
    @Generated
    @Selector("reloadFromOrigin")
    public native WKNavigation reloadFromOrigin();

    /**
     * The scroll view associated with the web view.
     */
    @Generated
    @Selector("scrollView")
    public native UIScrollView scrollView();

    /**
     * A SecTrustRef for the currently committed navigation.
     *

     * [@link] WKWebView @/link is key-value observing (KVO) compliant
     * for this property.
     */
    @Generated
    @Selector("serverTrust")
    public native SecTrustRef serverTrust();

    /**
     * A Boolean value indicating whether horizontal swipe gestures
     * will trigger back-forward list navigations.
     *

     * The default value is NO.
     */
    @Generated
    @Selector("setAllowsBackForwardNavigationGestures:")
    public native void setAllowsBackForwardNavigationGestures(boolean value);

    /**
     * A Boolean value indicating whether link preview is allowed for any
     * links inside this WKWebView.
     *

     * The default value is YES on Mac and iOS.
     */
    @Generated
    @Selector("setAllowsLinkPreview:")
    public native void setAllowsLinkPreview(boolean value);

    /**
     * The custom user agent string or nil if no custom user agent string has been set.
     */
    @Generated
    @Selector("setCustomUserAgent:")
    public native void setCustomUserAgent(String value);

    /**
     * The web view's navigation delegate.
     */
    @Generated
    @Selector("setNavigationDelegate:")
    public native void setNavigationDelegate_unsafe(@Mapped(ObjCObjectMapper.class) WKNavigationDelegate value);

    /**
     * The web view's navigation delegate.
     */
    @Generated
    public void setNavigationDelegate(@Mapped(ObjCObjectMapper.class) WKNavigationDelegate value) {
        Object __old = navigationDelegate();
        if (value != null) {
            org.moe.natj.objc.ObjCRuntime.associateObjCObject(this, value);
        }
        setNavigationDelegate_unsafe(value);
        if (__old != null) {
            org.moe.natj.objc.ObjCRuntime.dissociateObjCObject(this, __old);
        }
    }

    /**
     * The web view's user interface delegate.
     */
    @Generated
    @Selector("setUIDelegate:")
    public native void setUIDelegate_unsafe(@Mapped(ObjCObjectMapper.class) WKUIDelegate value);

    /**
     * The web view's user interface delegate.
     */
    @Generated
    public void setUIDelegate(@Mapped(ObjCObjectMapper.class) WKUIDelegate value) {
        Object __old = UIDelegate();
        if (value != null) {
            org.moe.natj.objc.ObjCRuntime.associateObjCObject(this, value);
        }
        setUIDelegate_unsafe(value);
        if (__old != null) {
            org.moe.natj.objc.ObjCRuntime.dissociateObjCObject(this, __old);
        }
    }

    /**
     * Stops loading all resources on the current page.
     */
    @Generated
    @Selector("stopLoading")
    public native void stopLoading();

    /**
     * The page title.
     *

     * [@link] WKWebView @/link is key-value observing (KVO) compliant
     * for this property.
     */
    @Generated
    @Selector("title")
    public native String title();

    @Runtime(ObjCRuntime.class)
    @Generated
    public interface Block_evaluateJavaScriptCompletionHandler {
        @Generated
        void call_evaluateJavaScriptCompletionHandler(@Mapped(ObjCObjectMapper.class) Object arg0, NSError error);
    }

    /**
     * Checks whether or not WKWebViews handle the given URL scheme by default.
     *
     * @param scheme The URL scheme to check.
     */
    @Generated
    @Selector("handlesURLScheme:")
    public static native boolean handlesURLScheme(String urlScheme);

    @Generated
    @Selector("modifyAnimationsWithRepeatCount:autoreverses:animations:")
    public static native void modifyAnimationsWithRepeatCountAutoreversesAnimations(@NFloat double count,
            boolean autoreverses,
            @ObjCBlock(name = "call_modifyAnimationsWithRepeatCountAutoreversesAnimations") UIView.Block_modifyAnimationsWithRepeatCountAutoreversesAnimations animations);

    @Generated
    @Selector("takeSnapshotWithConfiguration:completionHandler:")
    public native void takeSnapshotWithConfigurationCompletionHandler(WKSnapshotConfiguration snapshotConfiguration,
            @ObjCBlock(name = "call_takeSnapshotWithConfigurationCompletionHandler") Block_takeSnapshotWithConfigurationCompletionHandler completionHandler);

    @Runtime(ObjCRuntime.class)
    @Generated
    public interface Block_takeSnapshotWithConfigurationCompletionHandler {
        @Generated
        void call_takeSnapshotWithConfigurationCompletionHandler(UIImage snapshotImage, NSError error);
    }

    @Generated
    @Selector("callAsyncJavaScript:arguments:inFrame:inContentWorld:completionHandler:")
    public native void callAsyncJavaScriptArgumentsInFrameInContentWorldCompletionHandler(String functionBody,
            NSDictionary<String, ?> arguments, WKFrameInfo frame, WKContentWorld contentWorld,
            @ObjCBlock(name = "call_callAsyncJavaScriptArgumentsInFrameInContentWorldCompletionHandler") Block_callAsyncJavaScriptArgumentsInFrameInContentWorldCompletionHandler completionHandler);

    @Runtime(ObjCRuntime.class)
    @Generated
    public interface Block_callAsyncJavaScriptArgumentsInFrameInContentWorldCompletionHandler {
        @Generated
        void call_callAsyncJavaScriptArgumentsInFrameInContentWorldCompletionHandler(
                @Mapped(ObjCObjectMapper.class) Object arg0, NSError error);
    }

    /**
     * Create a PDF document representation from the web page currently displayed in the WKWebView
     *

     * If the WKPDFConfiguration is nil, the method will create a PDF document representing the bounds of the currently
     * displayed web page.
     * The completionHandler is passed the resulting PDF document data or an error.
     * The data can be used to create a PDFDocument object.
     * If the data is written to a file the resulting file is a valid PDF document.
     *
     * @param pdfConfiguration  An object that specifies how the PDF capture is configured.
     * @param completionHandler A block to invoke when the pdf document data is ready.
     */
    @Generated
    @Selector("createPDFWithConfiguration:completionHandler:")
    public native void createPDFWithConfigurationCompletionHandler(WKPDFConfiguration pdfConfiguration,
            @ObjCBlock(name = "call_createPDFWithConfigurationCompletionHandler") Block_createPDFWithConfigurationCompletionHandler completionHandler);

    @Runtime(ObjCRuntime.class)
    @Generated
    public interface Block_createPDFWithConfigurationCompletionHandler {
        @Generated
        void call_createPDFWithConfigurationCompletionHandler(NSData pdfDocumentData, NSError error);
    }

    /**
     * Create WebKit web archive data representing the current web content of the WKWebView
     *

     * WebKit web archive data represents a snapshot of web content.
     * It can be used to represent web content on a pasteboard, loaded into a WKWebView directly, and saved to a file
     * for later use.
     * The uniform type identifier kUTTypeWebArchive can be used get the related pasteboard type and MIME type.
     *
     * @param completionHandler A block to invoke when the web archive data is ready.
     */
    @Generated
    @Selector("createWebArchiveDataWithCompletionHandler:")
    public native void createWebArchiveDataWithCompletionHandler(
            @ObjCBlock(name = "call_createWebArchiveDataWithCompletionHandler") Block_createWebArchiveDataWithCompletionHandler completionHandler);

    @Runtime(ObjCRuntime.class)
    @Generated
    public interface Block_createWebArchiveDataWithCompletionHandler {
        @Generated
        void call_createWebArchiveDataWithCompletionHandler(NSData arg0, NSError arg1);
    }

    /**
     * Evaluates the given JavaScript string.
     *

     * The completionHandler is passed the result of the script evaluation or an error.
     *

     * Passing nil is equivalent to targeting the main frame.
     * If the frame argument no longer represents a valid frame by the time WebKit attempts to call the JavaScript
     * function your completion handler will be called with a WKErrorJavaScriptInvalidFrameTarget error.
     * This might happen for a number of reasons, including but not limited to:
     * - The target frame has been removed from the DOM via JavaScript
     * - A parent frame has navigated, destroying all of its previous child frames
     *

     * No matter which WKContentWorld you use to evaluate your JavaScript string, you can make changes to the underlying
     * web content. (e.g. the Document and its DOM structure)
     * Such changes will be visible to script executing in all WKContentWorlds.
     * Evaluating your JavaScript string can leave behind other changes to global state visibile to JavaScript. (e.g.
     * `window.myVariable = 1;`)
     * Those changes will only be visibile to scripts executed in the same WKContentWorld.
     * evaluateJavaScript: is a great way to set up global state for future JavaScript execution in a given world. (e.g.
     * Importing libraries/utilities that future JavaScript execution will rely on)
     * Once your global state is set up, consider using callAsyncJavaScript: for more flexible interaction with the
     * JavaScript programming model.
     *
     * @param javaScriptString  The JavaScript string to evaluate.
     * @param frame             A WKFrameInfo identifying the frame in which to evaluate the JavaScript string.
     * @param contentWorld      The WKContentWorld in which to evaluate the JavaScript string.
     * @param completionHandler A block to invoke when script evaluation completes or fails.
     */
    @Generated
    @Selector("evaluateJavaScript:inFrame:inContentWorld:completionHandler:")
    public native void evaluateJavaScriptInFrameInContentWorldCompletionHandler(String javaScriptString,
            WKFrameInfo frame, WKContentWorld contentWorld,
            @ObjCBlock(name = "call_evaluateJavaScriptInFrameInContentWorldCompletionHandler") Block_evaluateJavaScriptInFrameInContentWorldCompletionHandler completionHandler);

    @Runtime(ObjCRuntime.class)
    @Generated
    public interface Block_evaluateJavaScriptInFrameInContentWorldCompletionHandler {
        @Generated
        void call_evaluateJavaScriptInFrameInContentWorldCompletionHandler(@Mapped(ObjCObjectMapper.class) Object arg0,
                NSError error);
    }

    /**
     * Searches the page contents for the given string.
     *

     * If the WKFindConfiguration is nil, all of the default WKFindConfiguration values will be used.
     * A match found by the search is selected and the page is scrolled to reveal the selection.
     * The completion handler is called after the search completes.
     *
     * @param string            The string to search for.
     * @param configuration     A set of options configuring the search.
     * @param completionHandler A block to invoke when the search completes.
     */
    @Generated
    @Selector("findString:withConfiguration:completionHandler:")
    public native void findStringWithConfigurationCompletionHandler(String string, WKFindConfiguration configuration,
            @ObjCBlock(name = "call_findStringWithConfigurationCompletionHandler") Block_findStringWithConfigurationCompletionHandler completionHandler);

    @Runtime(ObjCRuntime.class)
    @Generated
    public interface Block_findStringWithConfigurationCompletionHandler {
        @Generated
        void call_findStringWithConfigurationCompletionHandler(WKFindResult result);
    }

    /**
     * The media type for the WKWebView
     *

     * The value of mediaType will override the normal value of the CSS media property.
     * Setting the value to nil will restore the normal value.
     * The default value is nil.
     */
    @Generated
    @Selector("mediaType")
    public native String mediaType();

    /**
     * The factor by which page content is scaled relative to the viewport.
     *

     * The default value is 1.0.
     * Changing this value is equivalent to web content setting the CSS "zoom"
     * property on all page content.
     */
    @Generated
    @Selector("pageZoom")
    @NFloat
    public native double pageZoom();

    /**
     * The media type for the WKWebView
     *

     * The value of mediaType will override the normal value of the CSS media property.
     * Setting the value to nil will restore the normal value.
     * The default value is nil.
     */
    @Generated
    @Selector("setMediaType:")
    public native void setMediaType(String value);

    /**
     * The factor by which page content is scaled relative to the viewport.
     *

     * The default value is 1.0.
     * Changing this value is equivalent to web content setting the CSS "zoom"
     * property on all page content.
     */
    @Generated
    @Selector("setPageZoom:")
    public native void setPageZoom(@NFloat double value);

    /**
     * The state of camera capture on a web page.
     *

     * [@link] WKWebView @/link is key-value observing (KVO) compliant
     * for this property.
     */
    @Generated
    @Selector("cameraCaptureState")
    @NInt
    public native long cameraCaptureState();

    @Generated
    @Selector("closeAllMediaPresentations")
    public native void closeAllMediaPresentations();

    /**
     * Closes all out-of-window media presentations in a WKWebView.
     *

     * Includes picture-in-picture and fullscreen.
     */
    @Generated
    @Selector("closeAllMediaPresentationsWithCompletionHandler:")
    public native void closeAllMediaPresentationsWithCompletionHandler(
            @ObjCBlock(name = "call_closeAllMediaPresentationsWithCompletionHandler") Block_closeAllMediaPresentationsWithCompletionHandler completionHandler);

    @Runtime(ObjCRuntime.class)
    @Generated
    public interface Block_closeAllMediaPresentationsWithCompletionHandler {
        @Generated
        void call_closeAllMediaPresentationsWithCompletionHandler();
    }

    /**
     * The interaction state for the WKWebView
     *

     * The interaction state (back-forward list, currently loaded page, scroll position, form data...) for the
     * WKWebView, which
     * can be retrieved and set on another WKWebView to restore state.
     */
    @Generated
    @Selector("interactionState")
    @MappedReturn(ObjCObjectMapper.class)
    public native Object interactionState();

    /**
     * Navigates to the requested file URL on the filesystem.
     *

     * If readAccessURL references a single file, only that file may be
     * loaded by WebKit.
     * If readAccessURL references a directory, files inside that file may be loaded by WebKit.
     *
     * @param request       The request specifying the file URL to which to navigate.
     * @param readAccessURL The URL to allow read access to.
     * @return A new navigation for the given file URL.
     */
    @Generated
    @Selector("loadFileRequest:allowingReadAccessToURL:")
    public native WKNavigation loadFileRequestAllowingReadAccessToURL(NSURLRequest request, NSURL readAccessURL);

    /**
     * Sets the webpage contents from the passed data as if it was the
     * response to the supplied request. The request is never actually sent to the
     * supplied URL, though loads of resources defined in the NSData object would
     * be performed.
     *
     * @param request  The request specifying the base URL and other loading details
     *                 to be used while interpreting the supplied data object.
     * @param response A response that is used to interpret the supplied data object.
     * @param data     The data to use as the contents of the webpage.
     * @return A new navigation.
     */
    @Generated
    @Selector("loadSimulatedRequest:response:responseData:")
    public native WKNavigation loadSimulatedRequestResponseResponseData(NSURLRequest request, NSURLResponse response,
            NSData data);

    /**
     * Sets the webpage contents from the passed HTML string as if it was
     * the response to the supplied request. The request is never actually sent to the
     * supplied URL, though loads of resources defined in the HTML string would be
     * performed.
     *
     * @param request The request specifying the base URL and other loading details
     *                to be used while interpreting the supplied data object.
     * @param string  The data to use as the contents of the webpage.
     * @return A new navigation.
     */
    @Generated
    @Selector("loadSimulatedRequest:responseHTMLString:")
    public native WKNavigation loadSimulatedRequestResponseHTMLString(NSURLRequest request, String string);

    @Generated
    @Selector("loadSimulatedRequest:withResponse:responseData:")
    public native WKNavigation loadSimulatedRequestWithResponseResponseData(NSURLRequest request,
            NSURLResponse response, NSData data);

    @Generated
    @Selector("loadSimulatedRequest:withResponseHTMLString:")
    public native WKNavigation loadSimulatedRequestWithResponseHTMLString(NSURLRequest request, String string);

    /**
     * The state of microphone capture on a web page.
     *

     * [@link] WKWebView @/link is key-value observing (KVO) compliant
     * for this property.
     */
    @Generated
    @Selector("microphoneCaptureState")
    @NInt
    public native long microphoneCaptureState();

    @Generated
    @Selector("pauseAllMediaPlayback:")
    public native void pauseAllMediaPlayback(
            @ObjCBlock(name = "call_pauseAllMediaPlayback") Block_pauseAllMediaPlayback completionHandler);

    @Runtime(ObjCRuntime.class)
    @Generated
    public interface Block_pauseAllMediaPlayback {
        @Generated
        void call_pauseAllMediaPlayback();
    }

    /**
     * Pauses media playback in WKWebView.
     *

     * Pauses media playback. Media in the page can be restarted by calling play() on a media element or resume() on an
     * AudioContext in JavaScript. A user can also use media controls to play media content after it has been paused.
     */
    @Generated
    @Selector("pauseAllMediaPlaybackWithCompletionHandler:")
    public native void pauseAllMediaPlaybackWithCompletionHandler(
            @ObjCBlock(name = "call_pauseAllMediaPlaybackWithCompletionHandler") Block_pauseAllMediaPlaybackWithCompletionHandler completionHandler);

    @Runtime(ObjCRuntime.class)
    @Generated
    public interface Block_pauseAllMediaPlaybackWithCompletionHandler {
        @Generated
        void call_pauseAllMediaPlaybackWithCompletionHandler();
    }

    @Generated
    @Selector("requestMediaPlaybackState:")
    public native void requestMediaPlaybackState(
            @ObjCBlock(name = "call_requestMediaPlaybackState") Block_requestMediaPlaybackState completionHandler);

    @Runtime(ObjCRuntime.class)
    @Generated
    public interface Block_requestMediaPlaybackState {
        @Generated
        void call_requestMediaPlaybackState(@NInt long arg0);
    }

    /**
     * Get the current media playback state of a WKWebView.
     *

     * If media playback exists, WKMediaPlaybackState will be one of three
     * values: WKMediaPlaybackPaused, WKMediaPlaybackSuspended, or WKMediaPlaybackPlaying.
     * If no media playback exists in the current WKWebView, WKMediaPlaybackState will equal
     * WKMediaPlaybackStateNone.
     *
     * @param completionHandler A block to invoke with the return value of the function call.
     */
    @Generated
    @Selector("requestMediaPlaybackStateWithCompletionHandler:")
    public native void requestMediaPlaybackStateWithCompletionHandler(
            @ObjCBlock(name = "call_requestMediaPlaybackStateWithCompletionHandler") Block_requestMediaPlaybackStateWithCompletionHandler completionHandler);

    @Runtime(ObjCRuntime.class)
    @Generated
    public interface Block_requestMediaPlaybackStateWithCompletionHandler {
        @Generated
        void call_requestMediaPlaybackStateWithCompletionHandler(@NInt long arg0);
    }

    @Generated
    @Selector("resumeAllMediaPlayback:")
    public native void resumeAllMediaPlayback(
            @ObjCBlock(name = "call_resumeAllMediaPlayback") Block_resumeAllMediaPlayback completionHandler);

    @Runtime(ObjCRuntime.class)
    @Generated
    public interface Block_resumeAllMediaPlayback {
        @Generated
        void call_resumeAllMediaPlayback();
    }

    /**
     * Resumes a download that failed or was canceled.
     *

     * The download needs its delegate to be set in the completionHandler to receive updates about its progress.
     *
     * @param resumeData        Data from a WKDownloadDelegate's didFailWithError or a WKDownload's cancel
     *                          completionHandler.
     * @param completionHandler A block called when the download has resumed.
     */
    @Generated
    @Selector("resumeDownloadFromResumeData:completionHandler:")
    public native void resumeDownloadFromResumeDataCompletionHandler(NSData resumeData,
            @ObjCBlock(name = "call_resumeDownloadFromResumeDataCompletionHandler") Block_resumeDownloadFromResumeDataCompletionHandler completionHandler);

    @Runtime(ObjCRuntime.class)
    @Generated
    public interface Block_resumeDownloadFromResumeDataCompletionHandler {
        @Generated
        void call_resumeDownloadFromResumeDataCompletionHandler(WKDownload arg0);
    }

    /**
     * Suspends or resumes all media playback in WKWebView.
     *

     * If suspended is true, this pauses media playback and blocks all attempts by the page or the user to resume until
     * setAllMediaPlaybackSuspended is called again with suspended set to false. Media playback should always be
     * suspended and resumed in pairs.
     *
     * @param suspended Whether media playback should be suspended or resumed.
     */
    @Generated
    @Selector("setAllMediaPlaybackSuspended:completionHandler:")
    public native void setAllMediaPlaybackSuspendedCompletionHandler(boolean suspended,
            @ObjCBlock(name = "call_setAllMediaPlaybackSuspendedCompletionHandler") Block_setAllMediaPlaybackSuspendedCompletionHandler completionHandler);

    @Runtime(ObjCRuntime.class)
    @Generated
    public interface Block_setAllMediaPlaybackSuspendedCompletionHandler {
        @Generated
        void call_setAllMediaPlaybackSuspendedCompletionHandler();
    }

    /**
     * Set camera capture state of a WKWebView.
     *

     * If value is WKMediaCaptureStateNone, this will stop any camera capture.
     * If value is WKMediaCaptureStateMuted, any active camera capture will become muted.
     * If value is WKMediaCaptureStateActive, any muted camera capture will become active.
     *
     * @param state             State to apply for capture.
     * @param completionHandler A block to invoke after the camera state has been changed.
     */
    @Generated
    @Selector("setCameraCaptureState:completionHandler:")
    public native void setCameraCaptureStateCompletionHandler(@NInt long state,
            @ObjCBlock(name = "call_setCameraCaptureStateCompletionHandler") Block_setCameraCaptureStateCompletionHandler completionHandler);

    @Runtime(ObjCRuntime.class)
    @Generated
    public interface Block_setCameraCaptureStateCompletionHandler {
        @Generated
        void call_setCameraCaptureStateCompletionHandler();
    }

    /**
     * The interaction state for the WKWebView
     *

     * The interaction state (back-forward list, currently loaded page, scroll position, form data...) for the
     * WKWebView, which
     * can be retrieved and set on another WKWebView to restore state.
     */
    @Generated
    @Selector("setInteractionState:")
    public native void setInteractionState(@Mapped(ObjCObjectMapper.class) Object value);

    /**
     * Set microphone capture state of a WKWebView.
     *

     * If value is WKMediaCaptureStateNone, this will stop any microphone capture.
     * If value is WKMediaCaptureStateMuted, any active microphone capture will become muted.
     * If value is WKMediaCaptureStateActive, any muted microphone capture will become active.
     *
     * @param state             state to apply for capture.
     * @param completionHandler A block to invoke after the camera state has been changed.
     */
    @Generated
    @Selector("setMicrophoneCaptureState:completionHandler:")
    public native void setMicrophoneCaptureStateCompletionHandler(@NInt long state,
            @ObjCBlock(name = "call_setMicrophoneCaptureStateCompletionHandler") Block_setMicrophoneCaptureStateCompletionHandler completionHandler);

    @Runtime(ObjCRuntime.class)
    @Generated
    public interface Block_setMicrophoneCaptureStateCompletionHandler {
        @Generated
        void call_setMicrophoneCaptureStateCompletionHandler();
    }

    @Generated
    @Selector("setUnderPageBackgroundColor:")
    public native void setUnderPageBackgroundColor(UIColor value);

    /**
     * Begins a download in the context of the currently displayed webpage as if the WKNavigationDelegate turned a
     * navigation into a download instead
     *

     * The download needs its delegate to be set in the completionHandler to receive updates about its progress.
     *
     * @param request           The request specifying the URL to download.
     * @param completionHandler A block called when the download has started.
     */
    @Generated
    @Selector("startDownloadUsingRequest:completionHandler:")
    public native void startDownloadUsingRequestCompletionHandler(NSURLRequest request,
            @ObjCBlock(name = "call_startDownloadUsingRequestCompletionHandler") Block_startDownloadUsingRequestCompletionHandler completionHandler);

    @Runtime(ObjCRuntime.class)
    @Generated
    public interface Block_startDownloadUsingRequestCompletionHandler {
        @Generated
        void call_startDownloadUsingRequestCompletionHandler(WKDownload arg0);
    }

    @Generated
    @Selector("suspendAllMediaPlayback:")
    public native void suspendAllMediaPlayback(
            @ObjCBlock(name = "call_suspendAllMediaPlayback") Block_suspendAllMediaPlayback completionHandler);

    @Runtime(ObjCRuntime.class)
    @Generated
    public interface Block_suspendAllMediaPlayback {
        @Generated
        void call_suspendAllMediaPlayback();
    }

    @Generated
    @Selector("themeColor")
    public native UIColor themeColor();

    @Generated
    @Selector("underPageBackgroundColor")
    public native UIColor underPageBackgroundColor();
}


text:
package xcordion.api;

import java.util.List;

/**
 * Provides a language/implementation-neutral abstraction of an XML element.
 * @param <T> type of a concrete implementation of this interface
 */
public interface TestElement<T extends TestElement<T>> {
	TestDocument<T> getDocument();
	List<T> getChildren();
	Integer getStartLine();
    String getAttribute(String name);
    String getAttribute(String namespaceUri, String name);
    T setAttribute(String name, String value);
    T setAttribute(String namespaceUri, String name, String value);

    /**
     * Returns the text content of this element and all children.  Note that this method will continue
     * to return the original text content of the element even after changes are made during the test.
     * @return The ORIGINAL value of this element, before any changes made over the course of the test
     */
	String getValue();

	String getLocalName();
    T addChild(String namespaceUri, String name);
    T addChild(String name);
	T getParent();

    /**
     * Gets the integer value of an attribute on the element having the specified local name and no namespace.
     * If no value or an unparseable value is specified, returns 1.
     * @param name the local name of the attribute to be read
     * @return value of this attribute as an integer, or 1 if the value cannot be read/parsed
     */
    int getIntAttribute(String name);

    /**
     * Gets the integer value of an attribute on the element having the specified namespace and local name.
     * If no value or an unparseable value is specified, returns 1.
     * @param namespaceUri URI of the namespace of the attribute to be read
     * @param name the local name of the attribute to be read
     * @return value of this attribute as an integer, or 1 if the value cannot be read/parsed
     */
    int getIntAttribute(String namespaceUri, String name);

	T duplicate();
	T insertChildAfter(T sibling, T toBeInserted);
	T remove(T childElement);
    T setText(String text);
    String asXml();
    List<TestAttribute> getAttributes();
    T addStyleClass(String styleClass);
    T appendNonBreakingSpaceIfBlank();
    T appendChild(T child);
    T prependChild(T child);
    T appendText(String text);
    T moveContentTo(T sibling);
    T getFirstChildNamed(String localName);
}


text:
import appuifw as ui

from pytriloquist import Const
from pytriloquist.btclient import BluetoothError
from pytriloquist.gui import Dialog

class ApplicationsDialog(Dialog):
    """
    Dialog used to manage applications.
    """
    def __init__(self, app, parent):
        Dialog.__init__(self, app, parent)

    def get_title(self):
        """Returns the dialog title.
        """
        return self.parent.get_title()

    def init_ui(self):
        """Initializes the user interface.
        """
        # Load the list of applications
        self.apps = []
        view = self.app.dbm.query(Const.DB_APPLICATIONS_SELECT)
        for i in range(view.count_line()):
            view.get_line()
            self.apps.append((view.col(1), view.col(2)))
            view.next_line()

        # Menu
        self.menu = [
            (_(u"Open")  , self.app_list_observe),
            (_(u"New")   , self.new_app),
            (_(u"Delete"), self.delete_app),
            (_(u"Rename"), self.rename_app),
        ]
        self.menu.extend(self.parent.menu)

        # Cannot display an empty Listbox
        if not self.apps:
            self.apps.append((-1, _("New")))
        self.app_list = ui.Listbox([app[1] for app in self.apps], self.app_list_observe)

    def display(self):
        """Displays the dialog on the device.
        """
        ui.app.body = self.app_list
        ui.app.menu = self.menu

    def app_list_observe(self):
        """Function called when an application is selected from the list.
        """
        selected = self.apps[self.app_list.current()]
        if selected[0] == -1:
            self.new_app()
        else:
            CommandsDialog(selected, self.app, self).execute()

    def new_app(self):
        """Adds a new application.
        """
        name = ui.query(_(u"Application name"), "text")
        if name:
            self.app.dbm.execute(Const.DB_APPLICATIONS_INSERT % name)
            self.execute(force=True)

    def delete_app(self):
        """Removes the selected application.
        """
        index = self.app_list.current()
        if index >= 0:
            selected = self.apps[index]
            if selected[0] >= 0:
                if ui.query(_(u"Delete \"%s\"?") % selected[1], "query"):
                    self.app.dbm.execute_atomic([
                        Const.DB_APPLICATIONS_DELETE % selected[0],
                        Const.DB_COMMANDS_APP_DELETE % selected[0]])
                    self.execute(force=True)
            else:
                ui.note(_(u"Cannot remove an action."), "error")

    def rename_app(self):
        """Renames the selected application.
        """
        index = self.app_list.current()
        if index >= 0:
            selected = self.apps[index]
            if selected[0] >= 0:
                name = ui.query(_(u"Application name"), "text", self.apps[index][1])
                if name:
                    self.app.dbm.execute(
                        Const.DB_APPLICATIONS_UPDATE % (name, selected[0]))
                    self.execute(force=True)
            else:
                ui.note(_(u"Cannot edit an action."), "error")

class CommandsDialog(Dialog):
    """
    Dialog used to manage the commands of an application.
    """
    def __init__(self, app_data, app, parent):
        Dialog.__init__(self, app, parent)
        self.app_data = app_data

    def get_title(self):
        """Returns the dialog title.
        """
        return self.app_data[1]

    def init_ui(self):
        """Initializes the user interface.
        """
        # Load the list of commands
        self.cmds = []

        view = self.app.dbm.query(Const.DB_COMMANDS_SELECT % self.app_data[0])
        for i in range(view.count_line()):
            view.get_line()
            self.cmds.append((view.col(1), view.col(2), view.col(3), view.col(4)))
            view.next_line()

        # Menu
        self.menu = [
            (_(u"Open")  , self.cmd_list_observe),
            (_(u"New")   , self.new_cmd),
            (_(u"Delete"), self.delete_cmd),
            (_(u"Edit")  , self.edit_cmd),
            (_(u"Back")  , self.back),
        ]

        # Cannot display an empty Listbox
        if not self.cmds:
            self.cmds.append((-1, -1, _("New"), ""))

        self.cmd_list = ui.Listbox([cmd[2] for cmd in self.cmds], self.cmd_list_observe)

    def display(self):
        """Displays the dialog on the device.
        """
        ui.app.body = self.cmd_list
        ui.app.menu = self.menu

    def cmd_list_observe(self):
        """Function called when a command is selected from the list.
        """
        selected = self.cmds[self.cmd_list.current()]
        if selected[0] == -1:
            self.new_cmd()
        else:
            try:
                self.app.btclient.send_command(0, selected[3])
            except BluetoothError, e:
                ui.note(_(e.msg), "error")

    def new_cmd(self):
        """Adds a new command.
        """
        EditCommandDialog(self.app_data, None, self.app, self).execute()

    def delete_cmd(self):
        """Removes the selected command.
        """
        index = self.cmd_list.current()
        if index >= 0:
            selected = self.cmds[index]
            if selected[0] >= 0:
                if ui.query(_(u"Delete \"%s\"?") % selected[2], "query"):
                    self.app.dbm.execute(Const.DB_COMMANDS_DELETE % selected[0])
                    self.execute(force=True)
            else:
                ui.note(_(u"Cannot remove an action."), "error")

    def edit_cmd(self):
        """Renames the selected command.
        """
        index = self.cmd_list.current()
        if index >= 0:
            selected = self.cmds[index]
            if selected[0] >= 0:
                EditCommandDialog(self.app_data, selected, self.app, self).execute()
            else:
                ui.note(_(u"Cannot edit an action."), "error")

class EditCommandDialog(Dialog):
    """
    Dialog used to add and edit application commands.
    """
    def __init__(self, app_data, command_data, app, parent):
        Dialog.__init__(self, app, parent)
        self.form_saved   = False
        self.app_data     = app_data
        self.command_data = command_data

    def get_title(self):
        """Returns the dialog title.
        """
        return self.app_data[1]

    def init_ui(self):
        """Initializes the user interface.
        """
        name    = u""
        command = u""

        if self.command_data:
            name    = self.command_data[2]
            command = self.command_data[3]

        # Form fields
        self.fields = [
            (_(u"Command name"), "text", name),
            (_(u"Command line"), "text", command),
        ]

        # Adjust flags
        self.initialized = True

        # Set up form
        self.form = ui.Form(self.fields, flags=ui.FFormEditModeOnly | ui.FFormDoubleSpaced)
        self.form.save_hook = self.save

    def display(self):
        """Displays the dialog on the device.
        """
        self.form_saved = False
        self.form.execute()
        self.parent.execute(force=self.form_saved)

    def get_name(self):
        """Gets the command name from the saved form.
        """
        if self.form_saved:
            return self.saved_data[0][2]

    def get_command(self):
        """Gets the command line from the saved form.
        """
        if self.form_saved:
            return self.saved_data[1][2]

    def save(self, data):
        """Adds or edits the command.
        """
        self.form_saved, self.saved_data = True, data

        if not self.command_data:
            self.app.dbm.execute(Const.DB_COMMANDS_INSERT % (
                self.app_data[0],
                self.get_name(),
                self.get_command()
            ))
        else:
            self.app.dbm.execute(Const.DB_COMMANDS_UPDATE % (
                self.get_name(),
                self.get_command(),
                self.command_data[0]
            ))

        return True


text:
.clear-fix {
  content: '';
  display: block;
  clear: both;
  visibility: hidden; }


text:
#include "atn/EmptyPredictionContext.h"
#include "misc/MurmurHash.h"
#include "atn/ArrayPredictionContext.h"
#include "RuleContext.h"
#include "ParserRuleContext.h"
#include "atn/RuleTransition.h"
#include "support/Arrays.h"
#include "support/CPPUtils.h"

#include "atn/PredictionContext.h"

using namespace antlr4;
using namespace antlr4::misc;
using namespace antlr4::atn;

using namespace antlrcpp;

size_t PredictionContext::globalNodeCount = 0;
const Ref<PredictionContext> PredictionContext::EMPTY = std::make_shared<EmptyPredictionContext>();

PredictionContext::PredictionContext(size_t cachedHashCode) : id(globalNodeCount++), cachedHashCode(cachedHashCode)  {
}

PredictionContext::~PredictionContext() {
}

Ref<PredictionContext> PredictionContext::fromRuleContext(const ATN &atn, RuleContext *outerContext) {
  if (outerContext == nullptr) {
    return PredictionContext::EMPTY;
  }

  // if we are in RuleContext of start rule, s, then PredictionContext
  // is EMPTY. Nobody called us. (if we are empty, return empty)
  if (outerContext->parent == nullptr || outerContext == &ParserRuleContext::EMPTY) {
    return PredictionContext::EMPTY;
  }

  // If we have a parent, convert it to a PredictionContext graph
  Ref<PredictionContext> parent = PredictionContext::fromRuleContext(atn, dynamic_cast<RuleContext *>(outerContext->parent));

  ATNState *state = atn.states.at(outerContext->invokingState);
  RuleTransition *transition = (RuleTransition *)state->transitions[0];
  return SingletonPredictionContext::create(parent, transition->followState->stateNumber);
}

bool PredictionContext::operator != (const PredictionContext &o) const {
  return !(*this == o);
}

bool PredictionContext::isEmpty() const {
  return this == EMPTY.get();
}

bool PredictionContext::hasEmptyPath() const {
  return getReturnState(size() - 1) == EMPTY_RETURN_STATE;
}

size_t PredictionContext::hashCode() const {
  return cachedHashCode;
}

size_t PredictionContext::calculateEmptyHashCode() {
  size_t hash = MurmurHash::initialize(INITIAL_HASH);
  hash = MurmurHash::finish(hash, 0);
  return hash;
}

size_t PredictionContext::calculateHashCode(std::weak_ptr<PredictionContext> parent, size_t returnState) {
  size_t hash = MurmurHash::initialize(INITIAL_HASH);
  hash = MurmurHash::update(hash, parent.lock());
  hash = MurmurHash::update(hash, returnState);
  hash = MurmurHash::finish(hash, 2);
  return hash;
}

size_t PredictionContext::calculateHashCode(const std::vector<std::weak_ptr<PredictionContext>> &parents,
                                            const std::vector<size_t> &returnStates) {
  size_t hash = MurmurHash::initialize(INITIAL_HASH);

  for (auto parent : parents) {
    if (parent.expired())
      hash = MurmurHash::update(hash, 0);
    else
      hash = MurmurHash::update(hash, parent.lock());
  }

  for (auto returnState : returnStates) {
    hash = MurmurHash::update(hash, returnState);
  }

  return MurmurHash::finish(hash, parents.size() + returnStates.size());
}

Ref<PredictionContext> PredictionContext::merge(const Ref<PredictionContext> &a,
  const Ref<PredictionContext> &b, bool rootIsWildcard, PredictionContextMergeCache *mergeCache) {

  assert(a && b);

  // share same graph if both same
  if (a == b) {
    return a;
  }

  if (is<SingletonPredictionContext>(a) && is<SingletonPredictionContext>(b)) {
    return mergeSingletons(std::dynamic_pointer_cast<SingletonPredictionContext>(a),
                           std::dynamic_pointer_cast<SingletonPredictionContext>(b), rootIsWildcard, mergeCache);
  }

  // At least one of a or b is array
  // If one is $ and rootIsWildcard, return $ as * wildcard
  if (rootIsWildcard) {
    if (is<EmptyPredictionContext>(a)) {
      return a;
    }
    if (is<EmptyPredictionContext>(b)) {
      return b;
    }
  }

  // convert singleton so both are arrays to normalize
  Ref<ArrayPredictionContext> left;
  if (is<SingletonPredictionContext>(a)) {
    left = std::make_shared<ArrayPredictionContext>(std::dynamic_pointer_cast<SingletonPredictionContext>(a));
  } else {
    left = std::dynamic_pointer_cast<ArrayPredictionContext>(a);
  }
  Ref<ArrayPredictionContext> right;
  if (is<SingletonPredictionContext>(b)) {
    right = std::make_shared<ArrayPredictionContext>(std::dynamic_pointer_cast<SingletonPredictionContext>(b));
  } else {
    right = std::dynamic_pointer_cast<ArrayPredictionContext>(b);
  }
  return mergeArrays(left, right, rootIsWildcard, mergeCache);
}

Ref<PredictionContext> PredictionContext::mergeSingletons(const Ref<SingletonPredictionContext> &a,
  const Ref<SingletonPredictionContext> &b, bool rootIsWildcard, PredictionContextMergeCache *mergeCache) {

  if (mergeCache != nullptr) { // Can be null if not given to the ATNState from which this call originates.
    auto iterator = mergeCache->find({ a, b });
    if (iterator != mergeCache->end()) {
      return iterator->second;
    }
    iterator = mergeCache->find({ b, a });
    if (iterator != mergeCache->end()) {
      return iterator->second;
    }
  }

  Ref<PredictionContext> rootMerge = mergeRoot(a, b, rootIsWildcard);
  if (rootMerge) {
    if (mergeCache != nullptr) {
      (*mergeCache)[{ a, b }] = rootMerge;
    }
    return rootMerge;
  }

  Ref<PredictionContext> parentA = a->parent;
  Ref<PredictionContext> parentB = b->parent;
  if (a->returnState == b->returnState) { // a == b
    Ref<PredictionContext> parent = merge(parentA, parentB, rootIsWildcard, mergeCache);

    // If parent is same as existing a or b parent or reduced to a parent, return it.
    if (parent == parentA) { // ax + bx = ax, if a=b
      return a;
    }
    if (parent == parentB) { // ax + bx = bx, if a=b
      return b;
    }

    // else: ax + ay = a'[x,y]
    // merge parents x and y, giving array node with x,y then remainders
    // of those graphs.  dup a, a' points at merged array
    // new joined parent so create new singleton pointing to it, a'
    Ref<PredictionContext> a_ = SingletonPredictionContext::create(parent, a->returnState);
    if (mergeCache != nullptr) {
      (*mergeCache)[{ a, b }] = a_;
    }
    return a_;
  } else {
    // a != b payloads differ
    // see if we can collapse parents due to $+x parents if local ctx
    std::weak_ptr<PredictionContext> singleParent;
    if (a == b || (parentA && parentA == parentB)) { // ax + bx = [a,b]x
      singleParent = a->parent;
    }
    if (!singleParent.expired()) { // parents are same, sort payloads and use same parent
      std::vector<size_t> payloads = { a->returnState, b->returnState };
      if (a->returnState > b->returnState) {
        payloads[0] = b->returnState;
        payloads[1] = a->returnState;
      }
      std::vector<std::weak_ptr<PredictionContext>> parents = { singleParent, singleParent };
      Ref<PredictionContext> a_ = std::make_shared<ArrayPredictionContext>(parents, payloads);
      if (mergeCache != nullptr) {
        (*mergeCache)[{ a, b }] = a_;
      }
      return a_;
    }

    // parents differ and can't merge them. Just pack together
    // into array; can't merge.
    // ax + by = [ax,by]
    Ref<PredictionContext> a_;
    if (a->returnState > b->returnState) { // sort by payload
      std::vector<size_t> payloads = { b->returnState, a->returnState };
      std::vector<std::weak_ptr<PredictionContext>> parents = { b->parent, a->parent };
      a_ = std::make_shared<ArrayPredictionContext>(parents, payloads);
    } else {
      std::vector<size_t> payloads = {a->returnState, b->returnState};
      std::vector<std::weak_ptr<PredictionContext>> parents = { a->parent, b->parent };
      a_ = std::make_shared<ArrayPredictionContext>(parents, payloads);
    }

    if (mergeCache != nullptr) {
      (*mergeCache)[{ a, b }] = a_;
    }
    return a_;
  }
}

Ref<PredictionContext> PredictionContext::mergeRoot(const Ref<SingletonPredictionContext> &a,
  const Ref<SingletonPredictionContext> &b, bool rootIsWildcard) {
  if (rootIsWildcard) {
    if (a == EMPTY) { // * + b = *
      return EMPTY;
    }
    if (b == EMPTY) { // a + * = *
      return EMPTY;
    }
  } else {
    if (a == EMPTY && b == EMPTY) { // $ + $ = $
      return EMPTY;
    }
    if (a == EMPTY) { // $ + x = [$,x]
      std::vector<size_t> payloads = { b->returnState, EMPTY_RETURN_STATE };
      std::vector<std::weak_ptr<PredictionContext>> parents = { b->parent, EMPTY };
      Ref<PredictionContext> joined = std::make_shared<ArrayPredictionContext>(parents, payloads);
      return joined;
    }
    if (b == EMPTY) { // x + $ = [$,x] ($ is always first if present)
      std::vector<size_t> payloads = { a->returnState, EMPTY_RETURN_STATE };
      std::vector<std::weak_ptr<PredictionContext>> parents = { a->parent, EMPTY };
      Ref<PredictionContext> joined = std::make_shared<ArrayPredictionContext>(parents, payloads);
      return joined;
    }
  }
  return nullptr;
}

Ref<PredictionContext> PredictionContext::mergeArrays(const Ref<ArrayPredictionContext> &a,
  const Ref<ArrayPredictionContext> &b, bool rootIsWildcard, PredictionContextMergeCache *mergeCache) {

  if (mergeCache != nullptr) {
    auto iterator = mergeCache->find({ a, b });
    if (iterator != mergeCache->end()) {
      return iterator->second;
    }
    iterator = mergeCache->find({ b, a });
    if (iterator != mergeCache->end()) {
      return iterator->second;
    }
  }

  // merge sorted payloads a + b => M
  size_t i = 0; // walks a
  size_t j = 0; // walks b
  size_t k = 0; // walks target M array

  std::vector<size_t> mergedReturnStates(a->returnStates.size() + b->returnStates.size());
  std::vector<std::weak_ptr<PredictionContext>> mergedParents(a->returnStates.size() + b->returnStates.size());

  // walk and merge to yield mergedParents, mergedReturnStates
  while (i < a->returnStates.size() && j < b->returnStates.size()) {
    Ref<PredictionContext> a_parent = a->parents[i];
    Ref<PredictionContext> b_parent = b->parents[j];
    if (a->returnStates[i] == b->returnStates[j]) {
      // same payload (stack tops are equal), must yield merged singleton
      size_t payload = a->returnStates[i];
      // $+$ = $
      bool both$ = payload == EMPTY_RETURN_STATE && a_parent && b_parent;
      bool ax_ax = (a_parent && b_parent) && a_parent == b_parent; // ax+ax -> ax
      if (both$ || ax_ax) {
        mergedParents[k] = a_parent; // choose left
        mergedReturnStates[k] = payload;
      }
      else { // ax+ay -> a'[x,y]
        Ref<PredictionContext> mergedParent = merge(a_parent, b_parent, rootIsWildcard, mergeCache);
        mergedParents[k] = mergedParent;
        mergedReturnStates[k] = payload;
      }
      i++; // hop over left one as usual
      j++; // but also skip one in right side since we merge
    } else if (a->returnStates[i] < b->returnStates[j]) { // copy a[i] to M
      mergedParents[k] = a_parent;
      mergedReturnStates[k] = a->returnStates[i];
      i++;
    }
    else { // b > a, copy b[j] to M
      mergedParents[k] = b_parent;
      mergedReturnStates[k] = b->returnStates[j];
      j++;
    }
    k++;
  }

  // copy over any payloads remaining in either array
  if (i < a->returnStates.size()) {
    for (std::vector<int>::size_type p = i; p < a->returnStates.size(); p++) {
      mergedParents[k] = a->parents[p];
      mergedReturnStates[k] = a->returnStates[p];
      k++;
    }
  } else {
    for (std::vector<int>::size_type p = j; p < b->returnStates.size(); p++) {
      mergedParents[k] = b->parents[p];
      mergedReturnStates[k] = b->returnStates[p];
      k++;
    }
  }

  // trim merged if we combined a few that had same stack tops
  if (k < mergedParents.size()) { // write index < last position; trim
    if (k == 1) { // for just one merged element, return singleton top
      Ref<PredictionContext> a_ = SingletonPredictionContext::create(mergedParents[0].lock(), mergedReturnStates[0]);
      if (mergeCache != nullptr) {
        (*mergeCache)[{ a, b }] = a_;
      }
      return a_;
    }
    //mergedParents = Arrays::copyOf(mergedParents, k);
    mergedParents.resize(k);
    //mergedReturnStates = Arrays::copyOf(mergedReturnStates, k);
    mergedReturnStates.resize(k);
  }

  Ref<ArrayPredictionContext> M = std::make_shared<ArrayPredictionContext>(mergedParents, mergedReturnStates);

  // if we created same array as a or b, return that instead
  // TO_DO: track whether this is possible above during merge sort for speed
  if (M == a) {
    if (mergeCache != nullptr) {
      (*mergeCache)[{ a, b }] = a;
    }
    return a;
  }
  if (M == b) {
    if (mergeCache != nullptr) {
      (*mergeCache)[{ a, b }] = b;
    }
    return b;
  }

  // This part differs from Java code. We have to recreate the context as the parents array is copied on creation.
  if (combineCommonParents(mergedParents))
    M = std::make_shared<ArrayPredictionContext>(mergedParents, mergedReturnStates);

  if (mergeCache != nullptr) {
    (*mergeCache)[{ a, b }] = M;
  }
  return M;
}

bool PredictionContext::combineCommonParents(std::vector<std::weak_ptr<PredictionContext>> &parents) {
  std::unordered_set<Ref<PredictionContext>, PredictionContextHasher, PredictionContextComparer> uniqueParents;

  for (size_t p = 0; p < parents.size(); ++p) {
    if (parents[p].expired())
      continue;
    Ref<PredictionContext> parent = parents[p].lock();
    if (uniqueParents.find(parent) == uniqueParents.end()) { // don't replace
      uniqueParents.insert(parent);
    }
  }

  if (uniqueParents.size() == parents.size())
    return false;

  // Don't resize the parents array, just update the content.
  for (size_t p = 0; p < parents.size(); ++p) {
    if (parents[p].expired())
      continue;
    parents[p] = *uniqueParents.find(parents[p].lock());
  }
  return true;
}

std::string PredictionContext::toDOTString(const Ref<PredictionContext> &context) {
  if (context == nullptr) {
    return "";
  }

  std::stringstream ss;
  ss << "digraph G {\n" << "rankdir=LR;\n";

  std::vector<Ref<PredictionContext>> nodes = getAllContextNodes(context);
  std::sort(nodes.begin(), nodes.end(), [](const Ref<PredictionContext> &o1, const Ref<PredictionContext> &o2) {
    return o1->id - o2->id;
  });

  for (auto current : nodes) {
    if (is<SingletonPredictionContext>(current)) {
      std::string s = std::to_string(current->id);
      ss << "  s" << s;
      std::string returnState = std::to_string(current->getReturnState(0));
      if (is<EmptyPredictionContext>(current)) {
        returnState = "$";
      }
      ss << " [label=\"" << returnState << "\"];\n";
      continue;
    }
    Ref<ArrayPredictionContext> arr = std::static_pointer_cast<ArrayPredictionContext>(current);
    ss << "  s" << arr->id << " [shape=box, label=\"" << "[";
    bool first = true;
    for (auto inv : arr->returnStates) {
      if (!first) {
       ss << ", ";
      }
      if (inv == EMPTY_RETURN_STATE) {
        ss << "$";
      } else {
        ss << inv;
      }
      first = false;
    }
    ss << "]";
    ss << "\"];\n";
  }

  for (auto current : nodes) {
    if (current == EMPTY) {
      continue;
    }
    for (size_t i = 0; i < current->size(); i++) {
      if (current->getParent(i).expired()) {
        continue;
      }
      ss << "  s" << current->id << "->" << "s" << current->getParent(i).lock()->id;
      if (current->size() > 1) {
        ss << " [label=\"parent[" << i << "]\"];\n";
      } else {
        ss << ";\n";
      }
    }
  }

  ss << "}\n";
  return ss.str();
}

// The "visited" map is just a temporary structure to control the retrieval process (which is recursive).
Ref<PredictionContext> PredictionContext::getCachedContext(const Ref<PredictionContext> &context,
  PredictionContextCache &contextCache, std::map<Ref<PredictionContext>, Ref<PredictionContext>> &visited) {
  if (context->isEmpty()) {
    return context;
  }

  {
    auto iterator = visited.find(context);
    if (iterator != visited.end())
      return iterator->second; // Not necessarly the same as context.
  }

  auto iterator = contextCache.find(context);
  if (iterator != contextCache.end()) {
    visited[context] = *iterator;

    return *iterator;
  }

  bool changed = false;

  std::vector<std::weak_ptr<PredictionContext>> parents(context->size());
  for (size_t i = 0; i < parents.size(); i++) {
    std::weak_ptr<PredictionContext> parent = getCachedContext(context->getParent(i).lock(), contextCache, visited);
    if (changed || parent.lock() != context->getParent(i).lock()) {
      if (!changed) {
        parents.clear();
        for (size_t j = 0; j < context->size(); j++) {
          parents.push_back(context->getParent(j));
        }

        changed = true;
      }

      parents[i] = parent;
    }
  }

  if (!changed) {
    contextCache.insert(context);
    visited[context] = context;

    return context;
  }

  Ref<PredictionContext> updated;
  if (parents.empty()) {
    updated = EMPTY;
  } else if (parents.size() == 1) {
    updated = SingletonPredictionContext::create(parents[0], context->getReturnState(0));
  } else {
    updated = std::make_shared<ArrayPredictionContext>(parents, std::dynamic_pointer_cast<ArrayPredictionContext>(context)->returnStates);
  }

  contextCache.insert(updated);
  visited[updated] = updated;
  visited[context] = updated;

  return updated;
}

std::vector<Ref<PredictionContext>> PredictionContext::getAllContextNodes(const Ref<PredictionContext> &context) {
  std::vector<Ref<PredictionContext>> nodes;
  std::set<PredictionContext *> visited;
  getAllContextNodes_(context, nodes, visited);
  return nodes;
}

void PredictionContext::getAllContextNodes_(const Ref<PredictionContext> &context, std::vector<Ref<PredictionContext>> &nodes,
  std::set<PredictionContext *> &visited) {

  if (visited.find(context.get()) != visited.end()) {
    return; // Already done.
  }

  visited.insert(context.get());
  nodes.push_back(context);

  for (size_t i = 0; i < context->size(); i++) {
    getAllContextNodes_(context->getParent(i).lock(), nodes, visited);
  }
}

std::string PredictionContext::toString() const {

  return antlrcpp::toString(this);
}

std::string PredictionContext::toString(Recognizer * /*recog*/) const {
  return toString();
}

std::vector<std::string> PredictionContext::toStrings(Recognizer *recognizer, int currentState) {
  return toStrings(recognizer, EMPTY, currentState);
}

std::vector<std::string> PredictionContext::toStrings(Recognizer *recognizer, const Ref<PredictionContext> &stop, int currentState) {

  std::vector<std::string> result;

  for (size_t perm = 0; ; perm++) {
    size_t offset = 0;
    bool last = true;
    PredictionContext *p = this;
    size_t stateNumber = currentState;

    std::stringstream ss;
    ss << "[";
    bool outerContinue = false;
    while (!p->isEmpty() && p != stop.get()) {
      size_t index = 0;
      if (p->size() > 0) {
        size_t bits = 1;
        while ((1ULL << bits) < p->size()) {
          bits++;
        }

        size_t mask = (1 << bits) - 1;
        index = (perm >> offset) & mask;
        last &= index >= p->size() - 1;
        if (index >= p->size()) {
          outerContinue = true;
          break;
        }
        offset += bits;
      }

      if (recognizer != nullptr) {
        if (ss.tellp() > 1) {
          // first char is '[', if more than that this isn't the first rule
          ss << ' ';
        }

        const ATN &atn = recognizer->getATN();
        ATNState *s = atn.states[stateNumber];
        std::string ruleName = recognizer->getRuleNames()[s->ruleIndex];
        ss << ruleName;
      } else if (p->getReturnState(index) != EMPTY_RETURN_STATE) {
        if (!p->isEmpty()) {
          if (ss.tellp() > 1) {
            // first char is '[', if more than that this isn't the first rule
            ss << ' ';
          }

          ss << p->getReturnState(index);
        }
      }
      stateNumber = p->getReturnState(index);
      p = p->getParent(index).lock().get();
    }

    if (outerContinue)
      continue;

    ss << "]";
    result.push_back(ss.str());

    if (last) {
      break;
    }
  }

  return result;
}