text:
package com.google.cloud.storage;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.fail;

import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.io.JsonEOFException;
import com.google.api.client.googleapis.json.GoogleJsonError;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.HttpResponseException;
import com.google.api.gax.retrying.ResultRetryAlgorithm;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.gson.stream.MalformedJsonException;
import java.io.IOException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLProtocolException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/**
 * Validate the behavior of our new "default" ResultRetryAlgorithms against that of the legacy retry
 * handling behavior.
 */
@RunWith(Parameterized.class)
public final class DefaultRetryHandlingBehaviorTest {
  private static final String DEFAULT_MESSAGE = "err_default_message";

  private final Case c;
  private final DefaultStorageRetryStrategy defaultStrategy;
  private final StorageRetryStrategy legacyStrategy;

  @SuppressWarnings("deprecation")
  public DefaultRetryHandlingBehaviorTest(Case c) {
    this.c = c;
    defaultStrategy = new DefaultStorageRetryStrategy();
    legacyStrategy = StorageRetryStrategy.getLegacyStorageRetryStrategy();
  }

  /**
   * For a specified {@link Case}
   *
   *

   *
Resolve the ResultRetryAlgorithm for the specific {@link HandlerCategory} for both
   *       default and legacy
   *
Evaluate the retryability of the throwable {@link Case#getThrowable()} against both of
   *       the resolved {@code ResultRetryAlgorithm}s
   *
Resolve the {@link Behavior} change if any between the two evaluation results
   *
Assert the behavior change matches the {@link Case#expectedBehavior expected behavior}
   *

   */
  @SuppressWarnings("ConstantConditions")
  @Test
  public void validateBehavior() {
    ResultRetryAlgorithm<?> defaultAlgorithm = c.handlerCategory.apply(defaultStrategy);
    ResultRetryAlgorithm<?> legacyAlgorithm = c.handlerCategory.apply(legacyStrategy);
    Throwable throwable = c.getThrowable();

    boolean defaultShouldRetryResult = defaultAlgorithm.shouldRetry(throwable, null);
    boolean legacyShouldRetryResult = legacyAlgorithm.shouldRetry(throwable, null);

    Behavior actualBehavior = null;
    String message = null;
    boolean shouldRetry = c.getExpectRetry().shouldRetry;
    if (shouldRetry && !defaultShouldRetryResult && legacyShouldRetryResult) {
      actualBehavior = Behavior.DEFAULT_MORE_STRICT;
      message = "default is more strict";
    } else if (shouldRetry && !defaultShouldRetryResult && !legacyShouldRetryResult) {
      actualBehavior = Behavior.SAME;
      message = "both are rejecting when we want a retry";
      fail(message);
    } else if (shouldRetry && defaultShouldRetryResult && legacyShouldRetryResult) {
      actualBehavior = Behavior.SAME;
      message = "both are allowing";
    } else if (shouldRetry && defaultShouldRetryResult && !legacyShouldRetryResult) {
      actualBehavior = Behavior.DEFAULT_MORE_PERMISSIBLE;
      message = "default is more permissive";
    } else if (!shouldRetry && !defaultShouldRetryResult && legacyShouldRetryResult) {
      actualBehavior = Behavior.DEFAULT_MORE_STRICT;
      message = "default is more strict";
    } else if (!shouldRetry && !defaultShouldRetryResult && !legacyShouldRetryResult) {
      actualBehavior = Behavior.SAME;
      message = "both are rejecting as expected";
    } else if (!shouldRetry && defaultShouldRetryResult && legacyShouldRetryResult) {
      actualBehavior = Behavior.SAME;
      message = "both are too permissive";
      fail(message);
    } else if (!shouldRetry && defaultShouldRetryResult && !legacyShouldRetryResult) {
      actualBehavior = Behavior.DEFAULT_MORE_PERMISSIBLE;
      message = "default is too permissive";
    }

    assertWithMessage(message).that(actualBehavior).isEqualTo(c.expectedBehavior);
  }

  /** Resolve all the test cases and assert all permutations have a case defined. */
  @Parameters(name = "{0}")
  public static Collection<Object[]> testCases() {

    // define the list of cases to be validated
    List<Case> cases = getAllCases();

    /* perform validation of the defined list of cases to ensure all permutations are defined */

    // calculate all the possible permutations
    ImmutableSet<String> expectedTokens =
        Arrays.stream(HandlerCategory.values())
            .flatMap(
                handlerCategory ->
                    Arrays.stream(ThrowableCategory.values())
                        .map(throwableCategory -> token(throwableCategory, handlerCategory)))
            .collect(toImmutableSet());

    // calculate the actual defined permutations
    ImmutableSet<String> actualTokens =
        cases.stream()
            .map(c -> token(c.throwableCategory, c.handlerCategory))
            .collect(toImmutableSet());

    // calculate the difference if any between expected and actual, then sort and listify
    ImmutableList<String> difference =
        Sets.difference(expectedTokens, actualTokens).stream().sorted().collect(toImmutableList());

    // ensure all permutations are accounted for, reporting any that haven't been and providing
    // a stub which can be used to easily define them.
    assertWithMessage("Missing mappings for tokens").that(difference).isEmpty();

    // wrap our case in an array for ultimate passing to the constructor
    return cases.stream().map(c -> new Object[] {c}).collect(toImmutableList());
  }

  /**
   * Generate a token which represents a permutation for which a {@link Case} must be defined.
   *
   *
If a case is not defined, this value will be reported and functions as a stub to easily
   * define a new {@code Case}.
   */
  private static String token(ThrowableCategory t, HandlerCategory h) {
    return String.format(
        "new Case(ThrowableCategory.%s, HandlerCategory.%s, /*TODO*/ null, /*TODO*/ null)",
        t.name(), h.name());
  }

  /**
   * An individual case we want to validate.
   *
   *
Given a {@link HandlerCategory} and {@link ThrowableCategory} validate the retryability and
   * behavior between default and legacy handlers.
   */
  static final class Case {

    private final HandlerCategory handlerCategory;
    private final ThrowableCategory throwableCategory;
    private final ExpectRetry expectRetry;
    private final Behavior expectedBehavior;

    Case(
        ThrowableCategory throwableCategory,
        HandlerCategory handlerCategory,
        ExpectRetry expectRetry,
        Behavior expectedBehavior) {
      this.handlerCategory = handlerCategory;
      this.throwableCategory = throwableCategory;
      this.expectRetry = expectRetry;
      this.expectedBehavior = expectedBehavior;
    }

    Throwable getThrowable() {
      return throwableCategory.throwable;
    }

    public ExpectRetry getExpectRetry() {
      return expectRetry;
    }

    @Override
    public String toString() {
      return "Case{"
          + "handlerCategory="
          + handlerCategory
          + ", throwableCategory="
          + throwableCategory
          + ", expectRetry="
          + expectRetry
          + ", expectedBehavior="
          + expectedBehavior
          + '}';
    }
  }

  /** Whether to expect a retry to happen or not */
  enum ExpectRetry {
    YES(true),
    NO(false);

    private final boolean shouldRetry;

    ExpectRetry(boolean shouldRetry) {
      this.shouldRetry = shouldRetry;
    }
  }

  /**
   * A category of handler type, and the ability to resolve the {@link ResultRetryAlgorithm} given a
   * {@link StorageRetryStrategy}
   */
  enum HandlerCategory implements Function<StorageRetryStrategy, ResultRetryAlgorithm<?>> {
    IDEMPOTENT,
    NONIDEMPOTENT;

    @Override
    public ResultRetryAlgorithm<?> apply(StorageRetryStrategy storageRetryStrategy) {
      switch (this) {
        case IDEMPOTENT:
          return storageRetryStrategy.getIdempotentHandler();
        case NONIDEMPOTENT:
          return storageRetryStrategy.getNonidempotentHandler();
        default:
          throw new IllegalStateException("Unmappable HandlerCategory: " + this.name());
      }
    }
  }

  /** Some states comparing behavior between default and legacy */
  enum Behavior {
    DEFAULT_MORE_PERMISSIBLE,
    SAME,
    DEFAULT_MORE_STRICT
  }

  /**
   * A set of exceptions we want to validate behavior for.
   *
   *
This class is an enum for convenience of specifying a closed set, along with providing easy
   * to read names in code thereby forgoing the need to maintain a separate set of strings.
   */
  enum ThrowableCategory {
    SOCKET_TIMEOUT_EXCEPTION(C.SOCKET_TIMEOUT_EXCEPTION),
    SOCKET_EXCEPTION(C.SOCKET_EXCEPTION),
    SSL_EXCEPTION(C.SSL_EXCEPTION),
    SSL_EXCEPTION_CONNECTION_SHUTDOWN(C.SSL_EXCEPTION_CONNECTION_SHUTDOWN),
    SSL_HANDSHAKE_EXCEPTION(C.SSL_HANDSHAKE_EXCEPTION),
    SSL_HANDSHAKE_EXCEPTION_CAUSED_BY_CERTIFICATE_EXCEPTION(
        C.SSL_HANDSHAKE_EXCEPTION_CERTIFICATE_EXCEPTION),
    INSUFFICIENT_DATA(C.INSUFFICIENT_DATA_WRITTEN),
    ERROR_WRITING_REQUEST_BODY(C.ERROR_WRITING_REQUEST_BODY),
    HTTP_RESPONSE_EXCEPTION_401(C.HTTP_401),
    HTTP_RESPONSE_EXCEPTION_403(C.HTTP_403),
    HTTP_RESPONSE_EXCEPTION_404(C.HTTP_404),
    HTTP_RESPONSE_EXCEPTION_408(C.HTTP_409),
    HTTP_RESPONSE_EXCEPTION_429(C.HTTP_429),
    HTTP_RESPONSE_EXCEPTION_500(C.HTTP_500),
    HTTP_RESPONSE_EXCEPTION_502(C.HTTP_502),
    HTTP_RESPONSE_EXCEPTION_503(C.HTTP_503),
    HTTP_RESPONSE_EXCEPTION_504(C.HTTP_504),
    STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_401(new StorageException(C.HTTP_401)),
    STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_403(new StorageException(C.HTTP_403)),
    STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_404(new StorageException(C.HTTP_404)),
    STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_408(new StorageException(C.HTTP_409)),
    STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_429(new StorageException(C.HTTP_429)),
    STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_500(new StorageException(C.HTTP_500)),
    STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_502(new StorageException(C.HTTP_502)),
    STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_503(new StorageException(C.HTTP_503)),
    STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_504(new StorageException(C.HTTP_504)),
    STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_401(new StorageException(C.JSON_401)),
    STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_403(new StorageException(C.JSON_403)),
    STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_404(new StorageException(C.JSON_404)),
    STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_408(new StorageException(C.JSON_408)),
    STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_429(new StorageException(C.JSON_429)),
    STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_500(new StorageException(C.JSON_500)),
    STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_502(new StorageException(C.JSON_502)),
    STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_503(new StorageException(C.JSON_503)),
    STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_504(new StorageException(C.JSON_504)),
    STORAGE_EXCEPTION_SOCKET_TIMEOUT_EXCEPTION(new StorageException(C.SOCKET_TIMEOUT_EXCEPTION)),
    STORAGE_EXCEPTION_SOCKET_EXCEPTION(StorageException.translate(C.SOCKET_EXCEPTION)),
    STORAGE_EXCEPTION_SSL_EXCEPTION(new StorageException(C.SSL_EXCEPTION)),
    STORAGE_EXCEPTION_SSL_EXCEPTION_CONNECTION_SHUTDOWN(
        new StorageException(C.SSL_EXCEPTION_CONNECTION_SHUTDOWN)),
    STORAGE_EXCEPTION_SSL_HANDSHAKE_EXCEPTION(new StorageException(C.SSL_HANDSHAKE_EXCEPTION)),
    STORAGE_EXCEPTION_SSL_HANDSHAKE_EXCEPTION_CAUSED_BY_CERTIFICATE_EXCEPTION(
        new StorageException(C.SSL_HANDSHAKE_EXCEPTION_CERTIFICATE_EXCEPTION)),
    STORAGE_EXCEPTION_INSUFFICIENT_DATA(new StorageException(C.INSUFFICIENT_DATA_WRITTEN)),
    STORAGE_EXCEPTION_ERROR_WRITING_REQUEST_BODY(
        new StorageException(C.ERROR_WRITING_REQUEST_BODY)),
    ILLEGAL_ARGUMENT_EXCEPTION(C.ILLEGAL_ARGUMENT_EXCEPTION),
    STORAGE_EXCEPTION_ILLEGAL_ARGUMENT_EXCEPTION(
        StorageException.coalesce(C.ILLEGAL_ARGUMENT_EXCEPTION)),
    STORAGE_EXCEPTION_0_INTERNAL_ERROR(
        new StorageException(0, "internalError", "internalError", null)),
    STORAGE_EXCEPTION_0_CONNECTION_CLOSED_PREMATURELY(
        new StorageException(
            0, "connectionClosedPrematurely", "connectionClosedPrematurely", null)),
    STORAGE_EXCEPTION_0_CONNECTION_CLOSED_PREMATURELY_IO_CAUSE(
        new StorageException(
            0,
            "connectionClosedPrematurely",
            "connectionClosedPrematurely",
            C.CONNECTION_CLOSED_PREMATURELY)),
    STORAGE_EXCEPTION_0_CONNECTION_CLOSED_PREMATURELY_IO_CAUSE_NO_REASON(
        StorageException.translate(C.CONNECTION_CLOSED_PREMATURELY)),
    STORAGE_EXCEPTION_0_IO_PREMATURE_EOF(StorageException.translate(C.IO_PREMATURE_EOF)),
    EMPTY_JSON_PARSE_ERROR(new IllegalArgumentException("no JSON input found")),
    JACKSON_EOF_EXCEPTION(C.JACKSON_EOF_EXCEPTION),
    STORAGE_EXCEPTION_0_JACKSON_EOF_EXCEPTION(
        new StorageException(0, "parse error", C.JACKSON_EOF_EXCEPTION)),
    GSON_MALFORMED_EXCEPTION(C.GSON_MALFORMED_EXCEPTION),
    STORAGE_EXCEPTION_0_GSON_MALFORMED_EXCEPTION(
        new StorageException(0, "parse error", C.GSON_MALFORMED_EXCEPTION)),
    IO_EXCEPTION(new IOException("no retry")),
    ;

    private final Throwable throwable;

    ThrowableCategory(Throwable throwable) {
      this.throwable = throwable;
    }

    public Throwable getThrowable() {
      return throwable;
    }

    /**
     * A class of constants for use by the containing enum.
     *
     *
Enums can't have static fields, so we use this class to hold constants which are used by
     * the enum values.
     */
    private static final class C {
      private static final SocketTimeoutException SOCKET_TIMEOUT_EXCEPTION =
          new SocketTimeoutException();
      private static final SocketException SOCKET_EXCEPTION = new SocketException();
      private static final SSLException SSL_EXCEPTION = new SSLException("unknown");
      private static final SSLException SSL_EXCEPTION_CONNECTION_SHUTDOWN =
          new SSLException("Connection has been shutdown: asdf");
      private static final SSLHandshakeException SSL_HANDSHAKE_EXCEPTION =
          newSslHandshakeExceptionWithCause(new SSLProtocolException(DEFAULT_MESSAGE));
      private static final SSLHandshakeException SSL_HANDSHAKE_EXCEPTION_CERTIFICATE_EXCEPTION =
          newSslHandshakeExceptionWithCause(new CertificateException());
      private static final IOException INSUFFICIENT_DATA_WRITTEN =
          new IOException("insufficient data written");
      private static final IOException ERROR_WRITING_REQUEST_BODY =
          new IOException("Error writing request body to server");
      private static final HttpResponseException HTTP_401 =
          newHttpResponseException(401, "Unauthorized");
      private static final HttpResponseException HTTP_403 =
          newHttpResponseException(403, "Forbidden");
      private static final HttpResponseException HTTP_404 =
          newHttpResponseException(404, "Not Found");
      private static final HttpResponseException HTTP_409 =
          newHttpResponseException(408, "Request Timeout");
      private static final HttpResponseException HTTP_429 =
          newHttpResponseException(429, "Too Many Requests");
      private static final HttpResponseException HTTP_500 =
          newHttpResponseException(500, "Internal Server Error");
      private static final HttpResponseException HTTP_502 =
          newHttpResponseException(502, "Bad Gateway");
      private static final HttpResponseException HTTP_503 =
          newHttpResponseException(503, "Service Unavailable");
      private static final HttpResponseException HTTP_504 =
          newHttpResponseException(504, "Gateway Timeout");
      private static final GoogleJsonError JSON_401 = newGoogleJsonError(401, "Unauthorized");
      private static final GoogleJsonError JSON_403 = newGoogleJsonError(403, "Forbidden");
      private static final GoogleJsonError JSON_404 = newGoogleJsonError(404, "Not Found");
      private static final GoogleJsonError JSON_408 = newGoogleJsonError(408, "Request Timeout");
      private static final GoogleJsonError JSON_429 = newGoogleJsonError(429, "Too Many Requests");
      private static final GoogleJsonError JSON_500 =
          newGoogleJsonError(500, "Internal Server Error");
      private static final GoogleJsonError JSON_502 = newGoogleJsonError(502, "Bad Gateway");
      private static final GoogleJsonError JSON_503 =
          newGoogleJsonError(503, "Service Unavailable");
      private static final GoogleJsonError JSON_504 = newGoogleJsonError(504, "Gateway Timeout");
      private static final IllegalArgumentException ILLEGAL_ARGUMENT_EXCEPTION =
          new IllegalArgumentException("illegal argument");
      private static final IOException CONNECTION_CLOSED_PREMATURELY =
          new IOException("simulated Connection closed prematurely");
      private static final JsonEOFException JACKSON_EOF_EXCEPTION =
          new JsonEOFException(null, JsonToken.VALUE_STRING, "parse-exception");
      private static final MalformedJsonException GSON_MALFORMED_EXCEPTION =
          new MalformedJsonException("parse-exception");
      private static final IOException IO_PREMATURE_EOF = new IOException("Premature EOF");

      private static HttpResponseException newHttpResponseException(
          int httpStatusCode, String name) {
        return new HttpResponseException.Builder(httpStatusCode, name, new HttpHeaders()).build();
      }

      private static GoogleJsonError newGoogleJsonError(int code, String message) {
        GoogleJsonError error = new GoogleJsonError();
        error.setCode(code);
        error.setMessage(message);
        return error;
      }

      private static SSLHandshakeException newSslHandshakeExceptionWithCause(Throwable cause) {
        SSLHandshakeException sslHandshakeException = new SSLHandshakeException(DEFAULT_MESSAGE);
        Throwable throwable = sslHandshakeException.initCause(cause);
        return (SSLHandshakeException) throwable;
      }
    }
  }

  /**
   * A corralled method which allows us to move the individual cases away from the rest of the code
   * since our code formatter is very strict and seems to feel 475 lines of code at 100 columns is
   * better than 90 lines at 200 columns.
   *
   *
this method returns a list that essentially is a table of where each row is an individual
   * test case
   *
   *

   *

   *     {@link ThrowableCategory throwable category}
   *     {@link HandlerCategory handler category}
   *     {@link ExpectRetry whether retry is expected}
   *     {@link Behavior what the expected behavior comparison is}
   *

   *

   *     {@link ThrowableCategory#STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_500 STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_500}
   *     {@link HandlerCategory#NONIDEMPOTENT NONIDEMPOTENT}
   *     {@link ExpectRetry#NO NO}
   *     {@link Behavior#DEFAULT_MORE_STRICT DEFAULT_MORE_STRICT}
   *

   *

   */
  private static ImmutableList<Case> getAllCases() {
    return ImmutableList.<Case>builder()
        .add(
            new Case(
                ThrowableCategory.ERROR_WRITING_REQUEST_BODY,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.DEFAULT_MORE_PERMISSIBLE),
            new Case(
                ThrowableCategory.ERROR_WRITING_REQUEST_BODY,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_401,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_401,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_403,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_403,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_404,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_404,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_408,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.DEFAULT_MORE_PERMISSIBLE),
            new Case(
                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_408,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_429,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.DEFAULT_MORE_PERMISSIBLE),
            new Case(
                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_429,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_500,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.DEFAULT_MORE_PERMISSIBLE),
            new Case(
                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_500,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_502,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.DEFAULT_MORE_PERMISSIBLE),
            new Case(
                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_502,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_503,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.DEFAULT_MORE_PERMISSIBLE),
            new Case(
                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_503,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_504,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.DEFAULT_MORE_PERMISSIBLE),
            new Case(
                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_504,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.ILLEGAL_ARGUMENT_EXCEPTION,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.ILLEGAL_ARGUMENT_EXCEPTION,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.INSUFFICIENT_DATA,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.DEFAULT_MORE_PERMISSIBLE),
            new Case(
                ThrowableCategory.INSUFFICIENT_DATA,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.SOCKET_EXCEPTION,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.DEFAULT_MORE_PERMISSIBLE),
            new Case(
                ThrowableCategory.SOCKET_EXCEPTION,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.SOCKET_TIMEOUT_EXCEPTION,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.DEFAULT_MORE_PERMISSIBLE),
            new Case(
                ThrowableCategory.SOCKET_TIMEOUT_EXCEPTION,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.SSL_EXCEPTION,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.SSL_EXCEPTION,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.SSL_EXCEPTION_CONNECTION_SHUTDOWN,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.DEFAULT_MORE_PERMISSIBLE),
            new Case(
                ThrowableCategory.SSL_EXCEPTION_CONNECTION_SHUTDOWN,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.SSL_HANDSHAKE_EXCEPTION,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.DEFAULT_MORE_PERMISSIBLE),
            new Case(
                ThrowableCategory.SSL_HANDSHAKE_EXCEPTION,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.SSL_HANDSHAKE_EXCEPTION_CAUSED_BY_CERTIFICATE_EXCEPTION,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.SSL_HANDSHAKE_EXCEPTION_CAUSED_BY_CERTIFICATE_EXCEPTION,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_ERROR_WRITING_REQUEST_BODY,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_ERROR_WRITING_REQUEST_BODY,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_401,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_401,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_403,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_403,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_404,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_404,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_408,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_408,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_429,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_429,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_500,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_500,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_502,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_502,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_503,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_503,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_504,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_504,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_401,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_401,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_403,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_403,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_404,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_404,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_408,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_408,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_429,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_429,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_500,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_500,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_502,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_502,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_503,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_503,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_504,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_504,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_ILLEGAL_ARGUMENT_EXCEPTION,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_ILLEGAL_ARGUMENT_EXCEPTION,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_INSUFFICIENT_DATA,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_INSUFFICIENT_DATA,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_SOCKET_EXCEPTION,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_SOCKET_EXCEPTION,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_SOCKET_TIMEOUT_EXCEPTION,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_SOCKET_TIMEOUT_EXCEPTION,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_SSL_EXCEPTION,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_SSL_EXCEPTION,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_SSL_EXCEPTION_CONNECTION_SHUTDOWN,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_SSL_EXCEPTION_CONNECTION_SHUTDOWN,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_SSL_HANDSHAKE_EXCEPTION,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_SSL_HANDSHAKE_EXCEPTION,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory
                    .STORAGE_EXCEPTION_SSL_HANDSHAKE_EXCEPTION_CAUSED_BY_CERTIFICATE_EXCEPTION,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory
                    .STORAGE_EXCEPTION_SSL_HANDSHAKE_EXCEPTION_CAUSED_BY_CERTIFICATE_EXCEPTION,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_0_CONNECTION_CLOSED_PREMATURELY,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_0_CONNECTION_CLOSED_PREMATURELY,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_0_CONNECTION_CLOSED_PREMATURELY_IO_CAUSE,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_0_CONNECTION_CLOSED_PREMATURELY_IO_CAUSE,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory
                    .STORAGE_EXCEPTION_0_CONNECTION_CLOSED_PREMATURELY_IO_CAUSE_NO_REASON,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory
                    .STORAGE_EXCEPTION_0_CONNECTION_CLOSED_PREMATURELY_IO_CAUSE_NO_REASON,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_0_IO_PREMATURE_EOF,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_0_IO_PREMATURE_EOF,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_0_INTERNAL_ERROR,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_0_INTERNAL_ERROR,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.DEFAULT_MORE_STRICT),
            new Case(
                ThrowableCategory.EMPTY_JSON_PARSE_ERROR,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.DEFAULT_MORE_PERMISSIBLE),
            new Case(
                ThrowableCategory.EMPTY_JSON_PARSE_ERROR,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.IO_EXCEPTION,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.IO_EXCEPTION,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.JACKSON_EOF_EXCEPTION,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.DEFAULT_MORE_PERMISSIBLE),
            new Case(
                ThrowableCategory.JACKSON_EOF_EXCEPTION,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_0_JACKSON_EOF_EXCEPTION,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.DEFAULT_MORE_PERMISSIBLE),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_0_JACKSON_EOF_EXCEPTION,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.GSON_MALFORMED_EXCEPTION,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.DEFAULT_MORE_PERMISSIBLE),
            new Case(
                ThrowableCategory.GSON_MALFORMED_EXCEPTION,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_0_GSON_MALFORMED_EXCEPTION,
                HandlerCategory.IDEMPOTENT,
                ExpectRetry.YES,
                Behavior.DEFAULT_MORE_PERMISSIBLE),
            new Case(
                ThrowableCategory.STORAGE_EXCEPTION_0_GSON_MALFORMED_EXCEPTION,
                HandlerCategory.NONIDEMPOTENT,
                ExpectRetry.NO,
                Behavior.SAME))
        .build();
  }
}


text:
package org.fxmisc.richtext.model;

import javafx.beans.value.ObservableValue;

import org.reactfx.EventStream;
import org.reactfx.EventStreamBase;
import org.reactfx.Subscription;
import org.reactfx.SuspendableNo;
import org.reactfx.collection.LiveList;
import org.reactfx.value.Val;

import java.util.Arrays;
import java.util.List;

/**
 * Content model for {@link org.fxmisc.richtext.GenericStyledArea}. Specifies edit operations
 * on paragraph's styles, segments (like text), and segments' style, but does not worry about view-related aspects
 * (e.g. scrolling).
 *
 * @param <PS> the paragraph style type
 * @param <SEG> the segment type
 * @param <S> the segment's style
 */
public interface EditableStyledDocument<PS, SEG, S> extends StyledDocument<PS, SEG, S> {

    /* ********************************************************************** *
     *                                                                        *
     * Observables                                                            *
     *                                                                        *
     * Observables are "dynamic" (i.e. changing) characteristics of an object.*
     * They are not directly settable by the client code, but change in       *
     * response to user input and/or API actions.                             *
     *                                                                        *
     * ********************************************************************** */

    ObservableValue<String> textProperty();

    int getLength();
    Val<Integer> lengthProperty();

    @Override
    LiveList<Paragraph<PS, SEG, S>> getParagraphs();

    /**
     * Read-only snapshot of the current state of this document.
     */
    ReadOnlyStyledDocument<PS, SEG, S> snapshot();

    /* ********************************************************************** *
     *                                                                        *
     * Event streams                                                          *
     *                                                                        *
     * ********************************************************************** */

    /**
     * Returns an {@link EventStream} that emits a {@link List} of {@link RichTextChange}s every time a change is made
     * to this document, even when such a change does not modify the underlying document in any way. The emitted
     * list will only have one item in it unless one used {@link #replaceMulti(List)}.
     */
    EventStream<List<RichTextChange<PS, SEG, S>>> multiRichChanges();

    /**
     * Returns an {@link EventStream} that emits a {@link List} of {@link PlainTextChange}s every time a non-style
     * change is made to this document. A style change would include setting a segment's style, but not changing
     * that segment or setting a paragraph's style. A non-style change would include adding/removing/modifying a
     * segment itself. The emitted list will only have one item in it unless one used {@link #replaceMulti(List)}.
     */
    default EventStream<List<PlainTextChange>> multiPlainChanges() {
        return multiRichChanges()
                .map(list -> Arrays.asList(list.stream()
                        .map(RichTextChange::toPlainTextChange)
                        // filter out rich changes where the style was changed but text wasn't added/removed
                        .filter(pc -> !pc.isIdentity())
                        .toArray(PlainTextChange[]::new)));
    }

    /**
     * Returns an {@link EventStream} that emits each {@link PlainTextChange} in {@link #multiPlainChanges()}'s
     * emitted list.
     */
    default EventStream<PlainTextChange> plainChanges() {
        return new EventStreamBase<PlainTextChange>() {
            @Override
            protected Subscription observeInputs() {
                return multiPlainChanges().subscribe(l -> l.forEach(this::emit));
            }
        };
    }

    /**
     * Returns an {@link EventStream} that emits each {@link RichTextChange} in {@link #multiRichChanges()}'s
     * emitted list.
     */
    default EventStream<RichTextChange<PS, SEG, S>> richChanges() {
        return new EventStreamBase<RichTextChange<PS, SEG, S>>() {
            @Override
            protected Subscription observeInputs() {
                return multiRichChanges().subscribe(list -> list.forEach(this::emit));
            }
        };
    }

    SuspendableNo beingUpdatedProperty();
    boolean isBeingUpdated();

    /* ********************************************************************** *
     *                                                                        *
     * Actions                                                                *
     *                                                                        *
     * Actions change the state of the object. They typically cause a change  *
     * of one or more observables and/or produce an event.                    *
     *                                                                        *
     * ********************************************************************** */

    /**
     * Replaces multiple portions of this document in one update.
     */
    void replaceMulti(List<Replacement<PS, SEG, S>> replacements);

    /**
     * Convenience method for {@link #replace(int, int, StyledDocument)} using a {@link Replacement} argument.
     */
    default void replace(Replacement<PS, SEG, S> replacement) {
        replace(replacement.getStart(), replacement.getEnd(), replacement.getDocument());
    }

    /**
     * Replaces the portion of this document {@code "from..to"} with the given {@code replacement}.
     *
     * @param start the absolute position in the document that starts the portion to replace
     * @param end the absolute position in the document that ends the portion to replace
     * @param replacement the document that replaces the removed portion of this document
     */
    void replace(int start, int end, StyledDocument<PS, SEG, S> replacement);

    /**
     * Sets the style of all segments in the given "from..to" range to the given style.
     *
     * @param from the absolute position in the document that starts the range to re-style
     * @param to the absolute position in the document that ends the range to re-style
     */
    void setStyle(int from, int to, S style);

    /**
     * Sets all segments in the given paragraph to the given style
     */
    void setStyle(int paragraphIndex, S style);

    /**
     * Sets the given range "fromCol..toCol" in the given paragraph to the given style
     */
    void setStyle(int paragraphIndex, int fromCol, int toCol, S style);

    /**
     * Replaces the style spans for the given range {@code "from..(from + styleSpans.length())"} with the given
     * style spans
     */
    void setStyleSpans(int from, StyleSpans<? extends S> styleSpens);

    /**
     * Replaces the style spans for the given range {@code "from..(from + styleSpans.length())"} in the given
     * paragraph with the given style spans
     */
    void setStyleSpans(int paragraphIndex, int from, StyleSpans<? extends S> styleSpens);

    /**
     * Sets the given paragraph to the given paragraph style
     */
    void setParagraphStyle(int paragraphIndex, PS style);

}

redpajama_set_name: RedPajamaGithub


text:
<TS language="hi" version="2.0">
<defaultcodec>UTF-8</defaultcodec>
<context>
    <name>AboutDialog</name>
    </context>
<context>
    <name>AddressBookPage</name>
    </context>
<context>
    <name>AddressTableModel</name>
    </context>
<context>
    <name>AskPassphraseDialog</name>
    </context>
<context>
    <name>BitcoinGUI</name>
    </context>
<context>
    <name>CoinControlDialog</name>
    <message>
        <source>0.00 BTC</source>
        <translation>0.00 BTC</translation>
    </message>
    <message>
        <source>Priority:</source>
        <translation>प्राथमिकता:</translation>
    </message>
    <message>
        <source>Fee:</source>
        <translation>शुल्क:</translation>
    </message>
    <message>
        <source>no</source>
        <translation>नहीं</translation>
    </message>
    <message>
        <source>After Fee:</source>
        <translation>पश्चात शुल्क:</translation>
    </message>
    <message>
        <source>Change:</source>
        <translation>परिवर्तन:</translation>
    </message>
    <message>
        <source>List mode</source>
        <translation>सूची विधा</translation>
    </message>
    <message>
        <source>Amount</source>
        <translation>राशि</translation>
    </message>
    <message>
        <source>Date</source>
        <translation>तिथि</translation>
    </message>
    <message>
        <source>Confirmations</source>
        <translation>पुष्टीकरण</translation>
    </message>
    <message>
        <source>Confirmed</source>
        <translation>पुष्टीकृत</translation>
    </message>
    <message>
        <source>Copy amount</source>
        <translation>राशि कॉपी करें</translation>
    </message>
    <message>
        <source>Copy transaction ID</source>
        <translation>लेनदेन की पहचान कॉपी करें</translation>
    </message>
    <message>
        <source>Copy quantity</source>
        <translation>मात्रा कॉपी करें</translation>
    </message>
    <message>
        <source>Copy fee</source>
        <translation>शुल्क कॉपी करें</translation>
    </message>
    <message>
        <source>Copy after fee</source>
        <translation> पश्चात शुल्क कॉपी करें</translation>
    </message>
    </context>
<context>
    <name>DisplayOptionsPage</name>
    </context>
<context>
    <name>EditAddressDialog</name>
    <message>
        <source>Edit Address</source>
        <translation>पता संपादन करें</translation>
    </message>
    <message>
        <source>&Address</source>
        <translation>पता</translation>
    </message>
    <message>
        <source>New receiving address</source>
        <translation>नई प्राप्ति पता</translation>
    </message>
    <message>
        <source>New sending address</source>
        <translation>नई प्रेषण पता</translation>
    </message>
    <message>
        <source>Edit receiving address</source>
        <translation>प्राप्ति पता संपादन करें</translation>
    </message>
    <message>
        <source>Edit sending address</source>
        <translation>प्रेषण पता संपादन करें</translation>
    </message>
    <message>
        <source>New key generation failed.</source>
        <translation>नई कुंजी उत्पादन विफल रहा है |</translation>
    </message>
</context>
<context>
    <name>GUIUtil::HelpMessageBox</name>
    </context>
<context>
    <name>MainOptionsPage</name>
    </context>
<context>
    <name>MintingTableModel</name>
    </context>
<context>
    <name>MintingView</name>
    </context>
<context>
    <name>MultisigAddressEntry</name>
    </context>
<context>
    <name>MultisigDialog</name>
    <message>
        <source>Fee:</source>
        <translation>शुल्क:</translation>
    </message>
    </context>
<context>
    <name>MultisigInputEntry</name>
    </context>
<context>
    <name>NetworkOptionsPage</name>
    </context>
<context>
    <name>OptionsDialog</name>
    </context>
<context>
    <name>OverviewPage</name>
    </context>
<context>
    <name>QRCodeDialog</name>
    </context>
<context>
    <name>RPCConsole</name>
    </context>
<context>
    <name>SendCoinsDialog</name>
    <message>
        <source>0.00 BTC</source>
        <translation>0.00 BTC</translation>
    </message>
    <message>
        <source>Priority:</source>
        <translation>प्राथमिकता:</translation>
    </message>
    <message>
        <source>Fee:</source>
        <translation>शुल्क:</translation>
    </message>
    <message>
        <source>no</source>
        <translation>नहीं</translation>
    </message>
    <message>
        <source>After Fee:</source>
        <translation>पश्चात शुल्क:</translation>
    </message>
    <message>
        <source>Copy quantity</source>
        <translation>मात्रा कॉपी करें</translation>
    </message>
    <message>
        <source>Copy amount</source>
        <translation>राशि कॉपी करें</translation>
    </message>
    <message>
        <source>Copy fee</source>
        <translation>शुल्क कॉपी करें</translation>
    </message>
    <message>
        <source>Copy after fee</source>
        <translation> पश्चात शुल्क कॉपी करें</translation>
    </message>
    </context>
<context>
    <name>SendCoinsEntry</name>
    </context>
<context>
    <name>SignVerifyMessageDialog</name>
    </context>
<context>
    <name>SplashScreen</name>
    </context>
<context>
    <name>TransactionDesc</name>
    <message>
        <source>Date</source>
        <translation>तिथि</translation>
    </message>
    <message>
        <source>Amount</source>
        <translation>राशि</translation>
    </message>
    </context>
<context>
    <name>TransactionDescDialog</name>
    </context>
<context>
    <name>TransactionTableModel</name>
    <message>
        <source>Date</source>
        <translation>तिथि</translation>
    </message>
    <message>
        <source>Amount</source>
        <translation>राशि</translation>
    </message>
    <message numerus="yes">
        <source>Open for %n block(s)</source>
        <translation><numerusform>Open for %n block</numerusform><numerusform>Open for %n blocks</numerusform></translation>
    </message>
    <message numerus="yes">
        <source>Mined balance will be available in %n more blocks</source>
        <translation><numerusform>Mined balance will be available in %n more block</numerusform><numerusform>Mined balance will be available in %n more blocks</numerusform></translation>
    </message>
    </context>
<context>
    <name>TransactionView</name>
    <message>
        <source>Copy amount</source>
        <translation>राशि कॉपी करें</translation>
    </message>
    <message>
        <source>Confirmed</source>
        <translation>पुष्टीकृत</translation>
    </message>
    <message>
        <source>Date</source>
        <translation>तिथि</translation>
    </message>
    <message>
        <source>Amount</source>
        <translation>राशि</translation>
    </message>
    </context>
<context>
    <name>WalletModel</name>
    </context>
<context>
    <name>WindowOptionsPage</name>
    </context>
<context>
    <name>bitcoin-core</name>
    <message>
        <source>Usage:</source>
        <translation>व्यवहार:</translation>
    </message>
    <message>
        <source>Lambocoin version</source>
        <translation>Lambocoin संस्करण</translation>
    </message>
    <message>
        <source>List commands</source>
        <translation>आदेशों सूचीबद्ध करें</translation>
    </message>
    <message>
        <source>Get help for a command</source>
        <translation>आदेश के लिए सहायता लें</translation>
    </message>
    <message>
        <source>Options:</source>
        <translation>विकल्प:</translation>
    </message>
    <message>
        <source>Generate coins</source>
        <translation>मुद्रांकन करें</translation>
    </message>
    <message>
        <source>Don't generate coins</source>
        <translation>मुद्रांकन न करें</translation>
    </message>
    <message>
        <source>Specify data directory</source>
        <translation>डेटा डायरेक्टरी निर्दिष्ट करें</translation>
    </message>
    <message>
        <source>Set database cache size in megabytes (default: 25)</source>
        <translation>मेगाबाइट में द्रुतिका आकार ठीक करें (डिफ़ॉल्ट : 25)</translation>
    </message>
    <message>
        <source>Set database disk log size in megabytes (default: 100)</source>
        <translation>मेगाबाइट में डेटाबेस डिस्क लॉग आकार ठीक करें (डिफ़ॉल्ट : 100)</translation>
    </message>
    <message>
        <source>Specify connection timeout (in milliseconds)</source>
        <translation>संबंध काल समापन निर्दिष्ट करें (मिलीसेकंड में )</translation>
    </message>
    <message>
        <source>Lambocoin</source>
        <translation>Lambocoin</translation>
    </message>
    </context>
</TS>


text:
<?php

namespace AppBundle\Entity;

/**
 * Description of Group
 *
 * @author Jonathan Claros <jclaros at lysoftbo.com>
 */
use FOS\UserBundle\Model\Group as BaseGroup;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_group")
 */
class Group extends BaseGroup{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var string
     * @ORM\Column(type="string", length=100)
     */

    protected $group_name;

    /**
     *
     * @var Array
     * @ORM\Column(type="array", nullable=true)
     */
    protected $group_roles;

    /**
     * @ORM\ManyToMany(targetEntity="User", mappedBy="groups")
     **/
    protected $users;

}


text:
#ifndef CAPU_ANDROID_ARM_V7L_FILE_H
#define CAPU_ANDROID_ARM_V7L_FILE_H

#include <capu/os/Android/File.h>

namespace capu
{
    namespace os
    {
        namespace arch
        {
            class File: private capu::os::File
            {
            public:
                File(const String& path);
                File(const File& parent, const capu::String& path);
                using capu::os::File::open;
                using capu::os::File::isOpen;
                using capu::os::File::isEof;
                using capu::os::File::read;
                using capu::os::File::write;
                using capu::os::File::seek;
                using capu::os::File::getCurrentPosition;
                using capu::os::File::flush;
                using capu::os::File::close;
                using capu::os::File::copyTo;
                using capu::os::File::renameTo;
                using capu::os::File::createFile;
                using capu::os::File::createDirectory;
                using capu::os::File::remove;
                using capu::os::File::exists;
                using capu::os::File::getFileName;
                using capu::os::File::getExtension;
                using capu::os::File::getPath;
                using capu::os::File::getParentPath;
                using capu::os::File::getSizeInBytes;
                using capu::os::File::isDirectory;
            };

            inline
            File::File(const String& path)
                : capu::os::File(path)
            {
            }

            inline
            File::File(const File& parent, const capu::String& path)
                : capu::os::File(parent, path)
            {
            }
        }
    }
}
#endif // CAPU_ANDROID_ARM_V7L_FILE_H


text:
{
  const Renderer = class {

    render(container, node) {
      const rootElement = this.createElement(node);
      node.element = rootElement;
      container.innerHTML = '';
      container.appendChild(rootElement);
    }
  };

  module.exports = Renderer;
}


text:
package com.intellij.psi.impl.source.tree.java;

import javax.annotation.Nonnull;

import com.intellij.lang.ASTNode;
import consulo.logging.Logger;
import com.intellij.psi.JavaElementVisitor;
import com.intellij.psi.PsiBlockStatement;
import com.intellij.psi.PsiCodeBlock;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.tree.ChildRoleBase;
import com.intellij.psi.impl.source.Constants;
import com.intellij.psi.impl.source.tree.ChildRole;
import com.intellij.psi.impl.source.tree.CompositePsiElement;

public class PsiBlockStatementImpl extends CompositePsiElement implements PsiBlockStatement {
  private static final Logger LOG = Logger.getInstance(PsiBlockStatementImpl.class);

  public PsiBlockStatementImpl() {
    super(Constants.BLOCK_STATEMENT);
  }

  @Override
  @Nonnull
  public PsiCodeBlock getCodeBlock() {
    return (PsiCodeBlock)findChildByRoleAsPsiElement(ChildRole.BLOCK);
  }

  @Override
  public ASTNode findChildByRole(int role) {
    LOG.assertTrue(ChildRole.isUnique(role));
    switch(role){
      default:
        return null;

      case ChildRole.BLOCK:
        return findChildByType(Constants.CODE_BLOCK);
    }
  }

  @Override
  public int getChildRole(ASTNode child) {
    LOG.assertTrue(child.getTreeParent() == this);
    if (child.getElementType() == Constants.CODE_BLOCK) {
      return ChildRole.BLOCK;
    }
    else {
      return ChildRoleBase.NONE;
    }
  }

  @Override
  public void accept(@Nonnull PsiElementVisitor visitor) {
    if (visitor instanceof JavaElementVisitor) {
      ((JavaElementVisitor)visitor).visitBlockStatement(this);
    }
    else {
      visitor.visitElement(this);
    }
  }

  public String toString() {
    return "PsiBlockStatement";
  }
}


text:
      ${nls.addFieldStat}

${nls.ok}

${nls.cancel}


text:
package com.opengamma.financial.convention.frequency;

import java.io.Serializable;

import com.opengamma.util.ArgumentChecker;

/**
 * Simple implementation of the frequency convention.
 */
public final class SimpleFrequency implements Frequency, Serializable {

  /** Serialization version. */
  private static final long serialVersionUID = 1L;

  /**
   * A frequency with a period of zero.
   */
  public static final SimpleFrequency NEVER = new SimpleFrequency(NEVER_NAME, 0);
  /**
   * A frequency with a period of one year.
   */
  public static final SimpleFrequency ANNUAL = new SimpleFrequency(ANNUAL_NAME, 1);
  /**
   * A frequency with a period of six months.
   */
  public static final SimpleFrequency SEMI_ANNUAL = new SimpleFrequency(SEMI_ANNUAL_NAME, 2);
  /**
   * A frequency with a period of three months.
   */
  public static final SimpleFrequency QUARTERLY = new SimpleFrequency(QUARTERLY_NAME, 4);
  /**
   * A frequency with a period of two months.
   */
  public static final SimpleFrequency BIMONTHLY = new SimpleFrequency(BIMONTHLY_NAME, 6);
  /**
   * A frequency with a period of one month.
   */
  public static final SimpleFrequency MONTHLY = new SimpleFrequency(MONTHLY_NAME, 12);
  /**
   * A frequency with a period of twenty eight days.
   */
  public static final SimpleFrequency TWENTY_EIGHT_DAYS = new SimpleFrequency(TWENTY_EIGHT_DAYS_NAME, 365. / 28);
  /**
   * A frequency with a period of three weeks.
   */
  public static final SimpleFrequency THREE_WEEKS = new SimpleFrequency(THREE_WEEK_NAME, 365. / 21);
  /**
   * A frequency with a period of two weeks.
   */
  public static final SimpleFrequency BIWEEKLY = new SimpleFrequency(BIWEEKLY_NAME, 26);
  /**
   * A frequency with a period of one week.
   */
  public static final SimpleFrequency WEEKLY = new SimpleFrequency(WEEKLY_NAME, 52);
  /**
   * A frequency with a period of one day.
   */
  public static final SimpleFrequency DAILY = new SimpleFrequency(DAILY_NAME, 365);
  /**
   * A continuous frequency.
   */
  // TODO where converting to/from say continuously compounded interest rates, can't use Double.MAX_VALUE, but need different formula
  public static final SimpleFrequency CONTINUOUS = new SimpleFrequency(CONTINUOUS_NAME, Double.MAX_VALUE);
  /**
   * A frequency with a period of four months
   */
  public static final SimpleFrequency FOUR_MONTHS = new SimpleFrequency(FOUR_MONTH_NAME, 3);
  /**
   * A frequency with a period of five months
   */
  public static final SimpleFrequency FIVE_MONTHS = new SimpleFrequency(FIVE_MONTH_NAME, 2.4);
  /**
   * A frequency with a period of seven months
   */
  public static final SimpleFrequency SEVEN_MONTHS = new SimpleFrequency(SEVEN_MONTH_NAME, 12. / 7);
  /**
   * A frequency with a period of eight months
   */
  public static final SimpleFrequency EIGHT_MONTHS = new SimpleFrequency(EIGHT_MONTH_NAME, 1.5);
  /**
   * A frequency with a period of nine months
   */
  public static final SimpleFrequency NINE_MONTHS = new SimpleFrequency(NINE_MONTH_NAME, 4. / 3);
  /**
   * A frequency with a period of ten months
   */
  public static final SimpleFrequency TEN_MONTHS = new SimpleFrequency(TEN_MONTH_NAME, 1.2);
  /**
   * A frequency with a period of eleven months
   */
  public static final SimpleFrequency ELEVEN_MONTHS = new SimpleFrequency(ELEVEN_MONTH_NAME, 12. / 11);
  /**
   * A frequency with a period of eighteen months
   */
  public static final SimpleFrequency EIGHTEEN_MONTHS = new SimpleFrequency(EIGHTEEN_MONTH_NAME, 12. / 18);

  /**
   * The name of the convention.
   */
  private final String _name;
  /**
   * The number of periods per year.
   */
  private final Double _periodsPerYear;

  /**
   * Creates an instance.
   *
   * @param name  the convention name, not null
   * @param periodsPerYear  the number of periods per year, greater than zero
   * @throws IllegalArgumentException if the name is null
   * @throws IllegalArgumentException if the frequency is zero or negative
   */
  /* package */SimpleFrequency(final String name, final double periodsPerYear) {
    ArgumentChecker.notNull(name, "name");
    ArgumentChecker.notNegative(periodsPerYear, "periods per year");
    _name = name;
    _periodsPerYear = periodsPerYear;
  }

  // -------------------------------------------------------------------------
  /**
   * @deprecated use getName()
   * @return the name of the convention
   */
  @Override
  @Deprecated
  public String getConventionName() {
    return getName();
  }

  @Override
  public String getName() {
    return _name;
  }

  /**
   * Gets the number of periods per year.
   *
   * @return the periods per year
   */
  public double getPeriodsPerYear() {
    return _periodsPerYear;
  }

  // -------------------------------------------------------------------------
  @Override
  public boolean equals(final Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj instanceof SimpleFrequency) {
      final SimpleFrequency other = (SimpleFrequency) obj;
      return _name.equals(other._name) && _periodsPerYear.equals(other._periodsPerYear);
    }
    return false;
  }

  @Override
  public int hashCode() {
    return _name.hashCode() ^ _periodsPerYear.hashCode();
  }

  @Override
  public String toString() {
    return "Frequency[" + "name = " + _name + " pa = " + _periodsPerYear + "]";
  }

  // -------------------------------------------------------------------------
  // REVIEW Elaine 2010-06-18 This is awful, but I'm not sure if we actually need SimpleFrequency,
  // so I'm going to use PeriodFrequency where possible and see if this class can be eliminated entirely
  /**
   * Converts this to a period frequency.
   *
   * @return the period frequency, not null
   */
  public PeriodFrequency toPeriodFrequency() {
    if (_name.equals(ANNUAL_NAME)) {
      return PeriodFrequency.ANNUAL;
    }
    if (_name.equals(BIMONTHLY_NAME)) {
      return PeriodFrequency.BIMONTHLY;
    }
    if (_name.equals(BIWEEKLY_NAME)) {
      return PeriodFrequency.BIWEEKLY;
    }
    if (_name.equals(CONTINUOUS_NAME)) {
      return PeriodFrequency.CONTINUOUS;
    }
    if (_name.equals(DAILY_NAME)) {
      return PeriodFrequency.DAILY;
    }
    if (_name.equals(MONTHLY_NAME)) {
      return PeriodFrequency.MONTHLY;
    }
    if (_name.equals(QUARTERLY_NAME)) {
      return PeriodFrequency.QUARTERLY;
    }
    if (_name.equals(SEMI_ANNUAL_NAME)) {
      return PeriodFrequency.SEMI_ANNUAL;
    }
    if (_name.equals(WEEKLY_NAME)) {
      return PeriodFrequency.WEEKLY;
    }
    if (_name.equals(FOUR_MONTH_NAME)) {
      return PeriodFrequency.FOUR_MONTHS;
    }
    if (_name.equals(FIVE_MONTH_NAME)) {
      return PeriodFrequency.FIVE_MONTHS;
    }
    if (_name.equals(SEVEN_MONTH_NAME)) {
      return PeriodFrequency.SEVEN_MONTHS;
    }
    if (_name.equals(EIGHT_MONTH_NAME)) {
      return PeriodFrequency.EIGHT_MONTHS;
    }
    if (_name.equals(NINE_MONTH_NAME)) {
      return PeriodFrequency.NINE_MONTHS;
    }
    if (_name.equals(TEN_MONTH_NAME)) {
      return PeriodFrequency.TEN_MONTHS;
    }
    if (_name.equals(ELEVEN_MONTH_NAME)) {
      return PeriodFrequency.ELEVEN_MONTHS;
    }
    if (_name.equals(EIGHTEEN_MONTH_NAME)) {
      return PeriodFrequency.EIGHTEEN_MONTHS;
    }
    if (_name.equals(TWENTY_EIGHT_DAYS_NAME)) {
      return PeriodFrequency.TWENTY_EIGHT_DAYS;
    }
    if (_name.equals(THREE_WEEK_NAME)) {
      return PeriodFrequency.THREE_WEEKS;
    }
    if (_name.equals(NEVER_NAME)) {
      return PeriodFrequency.NEVER;
    }
    throw new IllegalArgumentException("Cannot get a period frequency for " + toString());
  }

}


text:
package com.krazy.kcfw.common.beanvalidator;

/**
 * 添加Bean验证组
 * @author krazy
 *
 */
public interface AddGroup {

}


text:
import logging
import requests
from ballast.compat import unicode
from ballast.util import UrlBuilder
from ballast.discovery import Server, ServerList

class ConsulRestRecordList(ServerList):

    _SERVICE_URL = '/v1/catalog/service/'

    def __init__(self, base_url, service, dc=None, near=None, tag=None):
        super(ConsulRestRecordList, self).__init__()
        self.base_url = base_url
        self.service = service
        self.dc = dc
        self.near = near
        self.tag = tag
        self._logger = logging.getLogger(self.__module__)

    def get_servers(self):

        try:
            url = UrlBuilder.from_url(self.base_url)
            url.path(self._SERVICE_URL)
            url.append_path(self.service)

            if self.dc is not None:
                url.add_query_param('dc', self.dc)

            if self.near is not None:
                url.add_query_param('near', self.near)

            if self.tag is not None:
                url.add_query_param('tag', self.tag)

            response = requests.get(unicode(url))
            json = response.json()

            for entry in json:
                s = Server(
                    entry['Address'],
                    entry['ServicePort'],
                    ttl=10
                )

                self._logger.debug("Created server from Consul REST API record: %s", s)

                yield s

        except:
            return


text:
package scadla.backends.almond

import com.github.dzufferey.x3DomViewer.X3D
import scalatags.Text.all._
import squants.space.{Millimeters, LengthUnit}

class Config extends com.github.dzufferey.x3DomViewer.Config {

   var shapeAppearance = X3D.appearance(X3D.material(X3D.diffuseColor := "0.7 0.7 0.7"))
   val unit: LengthUnit = Millimeters
}


text:
Below is the API reference for the Facebook SDK for PHP.

# Core API

These classes are at the core of the Facebook SDK for PHP.

| Class name  | Description |
| ------------- | ------------- |
| [`Facebook\Facebook`](reference/Facebook.md)  | The main service object that helps tie all the SDK components together.  |
| [`Facebook\FacebookApp`](reference/FacebookApp.md)  | An entity that represents a Facebook app and is required to send requests to Graph.  |

# Authentication

These classes facilitate authenticating a Facebook user with OAuth 2.0.

| Class name  | Description |
| ------------- | ------------- |
| [`Facebook\Helpers\FacebookRedirectLoginHelper`](reference/FacebookRedirectLoginHelper.md)  | An OAuth 2.0 service to obtain a user access token from a redirect using a "Log in with Facebook" link.  |
| [`Facebook\Authentication\AccessToken`](reference/AccessToken.md)  | An entity that represents an access token.  |
| `Facebook\Authentication\AccessTokenMetadata`  | An entity that represents metadata from an access token.  |
| `Facebook\Authentication\OAuth2Client`  | An OAuth 2.0 client that sends and receives HTTP requests related to user authentication.  |

# Requests and Responses

These classes are used in a Graph API request/response cycle.

| Class name  | Description |
| ------------- | ------------- |
| [`Facebook\FacebookRequest`](reference/FacebookRequest.md) | An entity that represents an HTTP request to be sent to Graph.  |
| [`Facebook\FacebookResponse`](reference/FacebookResponse.md)  | An entity that represents an HTTP response from Graph.  |
| [`Facebook\FacebookBatchRequest`](reference/FacebookBatchRequest.md)  | An entity that represents an HTTP batch request to be sent to Graph.  |
| [`Facebook\FacebookBatchResponse`](reference/FacebookBatchResponse.md)  | An entity that represents an HTTP response from Graph after sending a batch request.  |
| [`Facebook\FacebookClient`](reference/FacebookClient.md)  | A service object that sends HTTP requests and receives HTTP responses to and from the Graph API.  |

# Signed Requests

Classes to help obtain and manage signed requests.

| Class name  | Description |
| ------------- | ------------- |
| [`Facebook\Helpers\FacebookJavaScriptHelper`](reference/FacebookJavaScriptHelper.md) | Used to obtain an access token or signed request from the cookie set by the JavaScript SDK.  |
| [`Facebook\Helpers\FacebookCanvasHelper`](reference/FacebookCanvasHelper.md)  | Used to obtain an access token or signed request from within the context of an app canvas.  |
| [`Facebook\Helpers\FacebookPageTabHelper`](reference/FacebookPageTabHelper.md)  | Used to obtain an access token or signed request from within the context of a page tab.  |
| [`Facebook\SignedRequest`](reference/SignedRequest.md)  | An entity that represents a signed request.  |

# Core Exceptions

These are the core exceptions that the SDK will throw when an error occurs.

| Class name  | Description |
| ------------- | ------------- |
| [`Facebook\Exceptions\FacebookSDKException`](reference/FacebookSDKException.md) | The base exception to all exceptions thrown by the SDK. Thrown when there is a non-Graph-response-related error.  |
| [`Facebook\Exceptions\FacebookResponseException`](reference/FacebookResponseException.md)  | The base exception to all Graph error responses. This exception is never thrown directly.  |

# Graph Nodes and Edges

Graph nodes are collections that represent nodes returned by the Graph API. And Graph edges are a collection of nodes returned from an edge on the Graph API.

| Class name  | Description |
| ------------- | ------------- |
| [`Facebook\GraphNodes\GraphNode`](reference/GraphNode.md) | The base collection object that represents a generic node.  |
| [`Facebook\GraphNodes\GraphEdge`](reference/GraphEdge.md)  | A collection of GraphNode\'s with special methods to help paginate over the edge.  |
| [`Facebook\GraphNodes\GraphAchievement`](reference/GraphNode.md#graphachievement-instance-methods) | A collection that represents an Achievement node.  |
| [`Facebook\GraphNodes\GraphAlbum`](reference/GraphNode.md#graphalbum-instance-methods)  | A collection that represents an Album node. |
| [`Facebook\GraphNodes\GraphLocation`](reference/GraphNode.md#graphlocation-instance-methods)  | A collection that represents a Location node. |
| [`Facebook\GraphNodes\GraphPage`](reference/GraphNode.md#graphpage-instance-methods)  | A collection that represents a Page node. |
| [`Facebook\GraphNodes\GraphPicture`](reference/GraphNode.md#graphpicture-instance-methods)  | A collection that represents a Picture node. |
| [`Facebook\GraphNodes\GraphUser`](reference/GraphNode.md#graphuser-instance-methods)  | A collection that represents a User node. |

# File Uploads

These are entities that represent files to be uploaded with a Graph request.

| Class name  | Description |
| ------------- | ------------- |
| [`Facebook\FileUpload\FacebookFile`](reference/FacebookFile.md) | Represents a generic file to be uploaded to the Graph API.  |
| [`Facebook\FileUpload\FacebookVideo`](reference/FacebookVideo.md)  | Represents a video file to be uploaded to the Graph API.  |

# Extensibility

You can overwrite certain functionality of the SDK by coding to an interface and injecting an instance of your custom functionality.

| Interface name  | Description |
| ------------- | ------------- |
| `Facebook\HttpClients\ FacebookHttpClientInterface` | An interface to code your own HTTP client implementation.  |
| `Facebook\Http\GraphRawResponse`  | An entity that is returned from an instance of a `FacebookHttpClientInterface` that represents a raw HTTP response from the Graph API.  |
| [`Facebook\PersistentData\PersistentDataInterface`](reference/PersistentDataInterface.md) | An interface to code your own persistent data storage implementation.  |
| [`Facebook\Url\UrlDetectionInterface`](reference/UrlDetectionInterface.md) | An interface to code your own URL detection logic.  |
| [`Facebook\PseudoRandomString\ PseudoRandomStringGeneratorInterface`](reference/PseudoRandomStringGeneratorInterface.md) | An interface to code your own cryptographically secure pseudo-random string generator.  |


text:
package org.ehcache.impl.internal.spi.loaderwriter;

import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.CacheConfiguration;
import org.ehcache.core.config.DefaultConfiguration;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.impl.config.loaderwriter.DefaultCacheLoaderWriterConfiguration;
import org.ehcache.impl.config.loaderwriter.DefaultCacheLoaderWriterProviderConfiguration;
import org.ehcache.spi.service.Service;
import org.ehcache.spi.service.ServiceProvider;
import org.ehcache.spi.loaderwriter.CacheLoaderWriter;
import org.ehcache.spi.service.ServiceConfiguration;
import org.junit.Test;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import static org.ehcache.config.builders.ResourcePoolsBuilder.heap;
import static org.ehcache.test.MockitoUtil.uncheckedGenericMock;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.instanceOf;

public class DefaultCacheLoaderWriterProviderTest {

  @Test
  public void testCacheConfigUsage() {
    final CacheManager manager = CacheManagerBuilder.newCacheManagerBuilder()
        .withCache("foo",
            CacheConfigurationBuilder.newCacheConfigurationBuilder(Object.class, Object.class, heap(10))
                .withService(new DefaultCacheLoaderWriterConfiguration(MyLoader.class))
                .build()).build(true);
    final Object foo = manager.getCache("foo", Object.class, Object.class).get(new Object());
    assertThat(foo, is(MyLoader.object));
  }

  @Test
  public void testCacheManagerConfigUsage() {

    final CacheConfiguration<Object, Object> cacheConfiguration = CacheConfigurationBuilder.newCacheConfigurationBuilder(Object.class, Object.class, heap(10))
        .build();

    final Map<String, CacheConfiguration<?, ?>> caches = new HashMap<>();
    caches.put("foo", cacheConfiguration);
    final DefaultConfiguration configuration = new DefaultConfiguration(caches, null, new DefaultCacheLoaderWriterProviderConfiguration()
        .addLoaderFor("foo", MyLoader.class));
    final CacheManager manager = CacheManagerBuilder.newCacheManager(configuration);
    manager.init();
    final Object foo = manager.getCache("foo", Object.class, Object.class).get(new Object());
    assertThat(foo, is(MyLoader.object));
  }

  @Test
  public void testCacheConfigOverridesCacheManagerConfig() {
    final CacheConfiguration<Object, Object> cacheConfiguration = CacheConfigurationBuilder.newCacheConfigurationBuilder(Object.class, Object.class, heap(10))
        .withService(new DefaultCacheLoaderWriterConfiguration(MyOtherLoader.class))
        .build();

    final Map<String, CacheConfiguration<?, ?>> caches = new HashMap<>();
    caches.put("foo", cacheConfiguration);
    final DefaultConfiguration configuration = new DefaultConfiguration(caches, null, new DefaultCacheLoaderWriterProviderConfiguration()
        .addLoaderFor("foo", MyLoader.class));
    final CacheManager manager = CacheManagerBuilder.newCacheManager(configuration);
    manager.init();
    final Object foo = manager.getCache("foo", Object.class, Object.class).get(new Object());
    assertThat(foo, is(MyOtherLoader.object));
  }

  @SuppressWarnings("unchecked")
  @Test
  public void testAddingCacheLoaderWriterConfigurationAtCacheLevel() {
    CacheManagerBuilder<CacheManager> cacheManagerBuilder = CacheManagerBuilder.newCacheManagerBuilder();
    Class<CacheLoaderWriter<?, ?>> klazz = (Class<CacheLoaderWriter<?, ?>>) (Class) (MyLoader.class);
    CacheManager cacheManager = cacheManagerBuilder.build(true);
    final Cache<Long, String> cache = cacheManager.createCache("cache",
        CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, heap(100))
            .withService(new DefaultCacheLoaderWriterConfiguration(klazz))
            .build());
    Collection<ServiceConfiguration<?, ?>> serviceConfiguration = cache.getRuntimeConfiguration()
        .getServiceConfigurations();
    assertThat(serviceConfiguration, hasItem(instanceOf(DefaultCacheLoaderWriterConfiguration.class)));
    cacheManager.close();
  }

  @Test
  public void testCreationConfigurationPreservedAfterStopStart() {
    DefaultCacheLoaderWriterProviderConfiguration configuration = new DefaultCacheLoaderWriterProviderConfiguration();
    configuration.addLoaderFor("cache", MyLoader.class);
    DefaultCacheLoaderWriterProvider loaderWriterProvider = new DefaultCacheLoaderWriterProvider(configuration);

    ServiceProvider<Service> serviceProvider = uncheckedGenericMock(ServiceProvider.class);
    loaderWriterProvider.start(serviceProvider);
    CacheConfiguration<Object, Object> cacheConfiguration = uncheckedGenericMock(CacheConfiguration.class);
    assertThat(loaderWriterProvider.createCacheLoaderWriter("cache", cacheConfiguration), instanceOf(MyLoader.class));

    loaderWriterProvider.stop();
    loaderWriterProvider.start(serviceProvider);

    assertThat(loaderWriterProvider.createCacheLoaderWriter("cache", cacheConfiguration), instanceOf(MyLoader.class));
  }

  public static class MyLoader implements CacheLoaderWriter<Object, Object> {

    private static final Object object = new Object() {
      @Override
      public String toString() {
        return MyLoader.class.getName() + "'s object";
      }
    };

    @Override
    public Object load(final Object key) {
      return object;
    }

    @Override
    public Map<Object, Object> loadAll(final Iterable<?> keys) {
      throw new UnsupportedOperationException("Implement me!");
    }

    private static Object lastWritten;

    @Override
    public void write(final Object key, final Object value) {
      lastWritten = value;
    }

    @Override
    public void writeAll(final Iterable<? extends Map.Entry<?, ?>> entries) {
      throw new UnsupportedOperationException("Implement me!");
    }

    @Override
    public void delete(final Object key) {
      throw new UnsupportedOperationException("Implement me!");
    }

    @Override
    public void deleteAll(final Iterable<?> keys) {
      throw new UnsupportedOperationException("Implement me!");
    }
  }

  public static class MyOtherLoader extends MyLoader {

    private static final Object object = new Object() {
      @Override
      public String toString() {
        return MyOtherLoader.class.getName() + "'s object";
      }
    };

    private static Object lastWritten;

    @Override
    public Object load(final Object key) {
      return object;
    }

    @Override
    public void write(final Object key, final Object value) {
      lastWritten = value;
    }

  }
}


text:
import unittest

from packaging.version import InvalidVersion, Version

from internal_backend.utilities.register import PantsReleases

def _branch_name(revision_str):
    return PantsReleases._branch_name(Version(revision_str))

class ReleasesTest(unittest.TestCase):
    def test_branch_name_master(self):
        self.assertEqual("master", _branch_name("1.1.0-dev1"))
        self.assertEqual("master", _branch_name("1.1.0dev1"))

    def test_branch_name_stable(self):
        self.assertEqual("1.1.x", _branch_name("1.1.0-rc1"))
        self.assertEqual("1.1.x", _branch_name("1.1.0rc1"))
        self.assertEqual("2.1.x", _branch_name("2.1.0"))
        self.assertEqual("1.2.x", _branch_name("1.2.0rc0-12345"))

        # A negative example: do not prepend `<number>.`, because
        # the first two numbers will be taken as branch name.
        self.assertEqual("12345.1.x", _branch_name("12345.1.2.0rc0"))

    def test_invalid_test_branch_name_stable_append_alphabet(self):
        with self.assertRaises(InvalidVersion):
            _branch_name("1.2.0rc0-abcd")

    def test_invalid_test_branch_name_stable_prepend_numbers(self):
        with self.assertRaises(InvalidVersion):
            _branch_name("12345-1.2.0rc0")

    def test_branch_name_unknown_suffix(self):
        with self.assertRaises(ValueError):
            _branch_name("1.1.0-anything1")


text:
<?php
namespace Admin\Api;

use Admin\Model\SecurityCodeModel;
use Common\Api\Api;
/**
 * Created by PhpStorm.
 * User: an
 * Date: 2015/9/2
 * Time: 15:34
 */
class SecurityCodeApi extends Api{

    const ADD="Admin/SecurityCode/add";

    const QUERY="Admin/SecurityCode/query";

    const QUERY_NO_PAGING="Admin/SecurityCode/queryNoPaging";

    const SAVE_BY_ID="Admin/SecurityCode/saveById";

    const GET_INFO = "Admin/SecurityCode/getInfo";

    /**
     * 验证验证码是否有效
     * @param $code         编码
     * @param $mobile       手机
     * @param $type         使用场景  (1. 注册  2. 密码更新)
     * @return array
     */
    const IS_LEGAL_CODE = "Admin/SecurityCode/isLegalCode";

    public function _init(){
        $this->model=new SecurityCodeModel();
    }

    /**
     * 验证验证码是否有效
     * @param $code         编码
     * @param $mobile       手机      不能为空
     * @param $type         使用场景  (1. 注册  2. 密码更新)
     * @return array
     */
    public function isLegalCode($code,$mobile,$type){

        $map=array(
            'code'=>$code,
            'accepter'=>$mobile,
            'type'=>$type,
        );
        $order="endtime desc";
        $result = $this->model->where($map)->order($order)->find();
        if($result === false){
            return $this->apiReturnErr($this->model->getDbError());
        }

        if(is_null($result)){
            return $this->apiReturnErr("验证码无效!");
        }

        $codeEntity = $result;

        if($codeEntity['status'] != 0){
            return $this->apiReturnErr("验证码已使用,请重新获取!");
        }

        if($codeEntity['endtime'] < NOW_TIME){
            return $this->apiReturnErr("验证码已过期,请重新获取!");
        }

        $result=$this->model->where(array('accepter'=>$mobile))->save(array('status'=>1));
        if($result === false){
            return $this->apiReturnErr($this->model->getDbError());
        }

        return $this->apiReturnSuc($codeEntity);

    }

}


text:
export COMPUTER_NAME="Laptop"
export LOCAL_HOST_NAME="laptop"
export HOST_NAME="laptop.local"

export BASH_RC_LOCAL=~/.bashrc.local

if [[ "$(uname -s)" == "Darwin" ]]; then
  export OS="osx"
else
  export OS="ubuntu"
fi

DOTFILES_DIR=~/.dotfiles

if [[ -L "$DOTFILES_DIR" ]]; then
  if [ "${OS}" == 'osx' ]; then
    DOTFILES_DIR="$(readlink $DOTFILES_DIR)";
  else
    DOTFILES_DIR="$(readlink -f $DOTFILES_DIR)";
  fi
fi

export DOTFILES_DIR

# Dotfiles bin path
PATH=$DOTFILES_DIR/bin:/usr/local/bin:\
/usr/local/sbin:$PATH

_PATH=$PATH:;
PATH=

while [ -n "$_PATH" ]; do
  SEGMENT=${_PATH%%:*}       # the first remaining entry

  case $PATH: in
    *:"$SEGMENT":*) ;;         # already there
    *) PATH=$PATH:$SEGMENT;;    # not there yet
  esac

  _PATH=${_PATH#*:}
done

PATH=${PATH#:}
unset _PATH SEGMENT

export PATH;

export APT_RC=/etc/apt/apt.conf.d/01dotfiles

export INPUT_RC=~/.inputrc

export GIT_CONF_LOCAL=~/.gitconfig.local

export CURL_RC=~/.curlrc

export DIR_COLORS=~/.dircolors

if [[ -e ~/.dotfiles/.tmux_installed ]]; then
  export TMUX_CONF=~/.tmux.conf
fi

export NVM_NODEJS_ORG_MIRROR=http://nodejs.org/dist
export NVM_DIR=/usr/local/nvm
export NPM_RC=~/.npmrc

export RVM_DIR=/usr/local/rvm
export rvm_path=/usr/local/rvm
export GEM_RC=~/.gemrc

if [[ -e ~/.dotfiles/.vim_installed ]]; then
  export VIM_DIR=/usr/local/etc/vim

  export MYVIMRC=~/.vimrc
  export MYVIMRC_LOCAL=~/.vimrc.local

  export MYGVIMRC=~/.gvimrc
  export MYGVIMRC_LOCAL=~/.gvimrc.local

  export VIMINIT="source $MYVIMRC"

  # Make vim the default editor
  export EDITOR='vim'
fi

# Ignore commands that start with spaces and duplicates
export HISTCONTROL=ignoreboth

# Increase the maximum number of lines contained in the
# history file (default value is 500)
export HISTFILESIZE=10000

# Don't add certain commands to the history file
export HISTIGNORE='&:[bf]g:c:clear:history:exit:q:pwd:* --help'

# Increase the maximum number of commands recorded in the
# command history (default value is 500)
export HISTSIZE=10000

# Prefer US English and use UTF-8 encoding
export LANG='en_US'
export LC_ALL='en_US.UTF-8'

# Use custom `less` colors for man pages
# https://www.gnu.org/software/termutils/manual/termutils-2.0/html_chapter/tput_1.html
export LESS_TERMCAP_md=$'\E[1;32m'   # begin bold mode
export LESS_TERMCAP_me=$'\E[0m'      # end bold mode
#export LESS_TERMCAP_us=$'\E[4;32m'   # begin underscore mode
#export LESS_TERMCAP_ue=$'\E[0m'      # end underscore mode

# Don't clear the screen after quitting a man page
export MANPAGER='less -X'

# Make new shells get the history lines from all previous
# shells instead of the default "last window closed" history
export PROMPT_COMMAND="history -a; $PROMPT_COMMAND"

if [[ "$COLORTERM" == gnome-* && "$TERM" == xterm ]] && infocmp gnome-256color &> /dev/null; then
  export TERM='gnome-256color'
elif infocmp xterm-256color &> /dev/null; then
  export TERM='xterm-256color'
fi

if [ "${OS}" == 'osx' ]; then
  LSCOLORS=''
  LSCOLORS+='gx' # Directory
  LSCOLORS+='fx' # Symbolic link
  LSCOLORS+='cx' # Socket
  LSCOLORS+='dx' # Pipe
  LSCOLORS+='cx' # Executable
  LSCOLORS+='eg' # Block special
  LSCOLORS+='ed' # Character special
  LSCOLORS+='ab' # Executable with setuid bit set
  LSCOLORS+='ag' # Executable with setgid bit set
  LSCOLORS+='cc' # Directory writable to others, with sticky bit
  LSCOLORS+='bd' # Directory writable to others, without sticky bit

  export LSCOLORS
elif [ "${OS}" == 'ubuntu' ]; then
  LS_COLORS=''
  LS_COLORS+='no=0;39:'   # global default
  LS_COLORS+='di=0;36:'   # directory
  LS_COLORS+='ex=0;32:'   # executable file
  LS_COLORS+='fi=0;39:'   # file
  LS_COLORS+='ec=:'       # non-filename text
  LS_COLORS+='mi=1;31:'   # non-existent file pointed to by a symlink
  LS_COLORS+='ln=target:' # symbolic link
  LS_COLORS+='or=31;01'   # symbolic link pointing to a non-existent file

  export LS_COLORS
fi


text:
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk

# ----------------------------------------------------
# Application version
# ----------------------------------------------------
include ../../vsn.mk
VSN=$(ERL_DOCGEN_VSN)

# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
RELSYSDIR = $(RELEASE_PATH)/lib/erl_docgen-$(VSN)

# ----------------------------------------------------
# Target Specs
# ----------------------------------------------------

ESCRIPT_FILES= \
	codeline_preprocessing.escript \
	xml_from_edoc.escript

# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------

# ----------------------------------------------------
# Targets
# ----------------------------------------------------
debug opt:

docs:

clean:
	$(RM) $(TARGET_FILES)

# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
include $(ERL_TOP)/make/otp_release_targets.mk

release_spec: opt
	$(INSTALL_DIR) $(RELSYSDIR)/priv/bin
	$(INSTALL_SCRIPT) $(ESCRIPT_FILES) $(RELSYSDIR)/priv/bin

release_docs_spec:

release_tests_spec: