text:
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.storage.blob;

import com.azure.core.http.HttpPipeline;
import com.azure.core.http.rest.Response;
import com.azure.core.util.FluxUtil;
import com.azure.core.util.logging.ClientLogger;
import com.azure.storage.blob.implementation.models.EncryptionScope;
import com.azure.storage.blob.implementation.util.ModelHelper;
import com.azure.storage.blob.models.AccessTier;
import com.azure.storage.blob.models.BlobHttpHeaders;
import com.azure.storage.blob.models.BlobRange;
import com.azure.storage.blob.models.BlobRequestConditions;
import com.azure.storage.blob.models.BlockBlobItem;
import com.azure.storage.blob.models.CpkInfo;
import com.azure.storage.blob.models.CustomerProvidedKey;
import com.azure.storage.blob.models.ParallelTransferOptions;
import com.azure.storage.blob.options.BlobParallelUploadOptions;
import com.azure.storage.blob.options.BlobUploadFromFileOptions;
import com.azure.storage.blob.options.BlockBlobCommitBlockListOptions;
import com.azure.storage.blob.options.BlockBlobSimpleUploadOptions;
import com.azure.storage.blob.specialized.AppendBlobAsyncClient;
import com.azure.storage.blob.specialized.BlobAsyncClientBase;
import com.azure.storage.blob.specialized.BlockBlobAsyncClient;
import com.azure.storage.blob.specialized.BlockBlobClient;
import com.azure.storage.blob.specialized.PageBlobAsyncClient;
import com.azure.storage.blob.specialized.SpecializedBlobClientBuilder;
import com.azure.storage.common.Utility;
import com.azure.storage.common.implementation.Constants;
import com.azure.storage.common.implementation.StorageImplUtils;
import com.azure.storage.common.implementation.UploadBufferPool;
import com.azure.storage.common.implementation.UploadUtils;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.azure.core.util.FluxUtil.monoError;
import static java.nio.charset.StandardCharsets.UTF_8;

/**
 * This class provides a client that contains generic blob operations for Azure Storage Blobs. Operations allowed by the
 * client are uploading and downloading, copying a blob, retrieving and setting metadata, retrieving and setting HTTP
 * headers, and deleting and un-deleting a blob.
 *
 *

 * This client is instantiated through {@link BlobClientBuilder} or retrieved via {@link
 * BlobContainerAsyncClient#getBlobAsyncClient(String) getBlobAsyncClient}.
 *
 *

 * For operations on a specific blob type (i.e append, block, or page) use {@link #getAppendBlobAsyncClient()
 * getAppendBlobAsyncClient}, {@link #getBlockBlobAsyncClient() getBlockBlobAsyncClient}, or {@link
 * #getPageBlobAsyncClient() getPageBlobAsyncClient} to construct a client that allows blob specific operations.
 *
 *

 * Please refer to the
 * Azure
 * Docs for more information.
 */
public class BlobAsyncClient extends BlobAsyncClientBase {
    /**
     * The block size to use if none is specified in parallel operations.
     */
    public static final int BLOB_DEFAULT_UPLOAD_BLOCK_SIZE = 4 * Constants.MB;

    /**
     * The number of buffers to use if none is specied on the buffered upload method.
     */
    public static final int BLOB_DEFAULT_NUMBER_OF_BUFFERS = 8;

    /**
     * If a blob is known to be greater than 100MB, using a larger block size will trigger some server-side
     * optimizations. If the block size is not set and the size of the blob is known to be greater than 100MB, this
     * value will be used.
     */
    public static final int BLOB_DEFAULT_HTBB_UPLOAD_BLOCK_SIZE = 8 * Constants.MB;

    static final long BLOB_MAX_UPLOAD_BLOCK_SIZE = 4000L * Constants.MB;
    private final ClientLogger logger = new ClientLogger(BlobAsyncClient.class);

    /**
     * Protected constructor for use by {@link BlobClientBuilder}.
     *
     * @param pipeline The pipeline used to send and receive service requests.
     * @param url The endpoint where to send service requests.
     * @param serviceVersion The version of the service to receive requests.
     * @param accountName The storage account name.
     * @param containerName The container name.
     * @param blobName The blob name.
     * @param snapshot The snapshot identifier for the blob, pass {@code null} to interact with the blob directly.
     * @param customerProvidedKey Customer provided key used during encryption of the blob's data on the server, pass
     * {@code null} to allow the service to use its own encryption.
     */
    protected BlobAsyncClient(HttpPipeline pipeline, String url, BlobServiceVersion serviceVersion, String accountName,
        String containerName, String blobName, String snapshot, CpkInfo customerProvidedKey) {
        super(pipeline, url, serviceVersion, accountName, containerName, blobName, snapshot, customerProvidedKey);
    }

    /**
     * Protected constructor for use by {@link BlobClientBuilder}.
     *
     * @param pipeline The pipeline used to send and receive service requests.
     * @param url The endpoint where to send service requests.
     * @param serviceVersion The version of the service to receive requests.
     * @param accountName The storage account name.
     * @param containerName The container name.
     * @param blobName The blob name.
     * @param snapshot The snapshot identifier for the blob, pass {@code null} to interact with the blob directly.
     * @param customerProvidedKey Customer provided key used during encryption of the blob's data on the server, pass
     * {@code null} to allow the service to use its own encryption.
     * @param encryptionScope Encryption scope used during encryption of the blob's data on the server, pass
     * {@code null} to allow the service to use its own encryption.
     */
    protected BlobAsyncClient(HttpPipeline pipeline, String url, BlobServiceVersion serviceVersion, String accountName,
        String containerName, String blobName, String snapshot, CpkInfo customerProvidedKey,
        EncryptionScope encryptionScope) {
        super(pipeline, url, serviceVersion, accountName, containerName, blobName, snapshot, customerProvidedKey,
            encryptionScope);
    }

    /**
     * Protected constructor for use by {@link BlobClientBuilder}.
     *
     * @param pipeline The pipeline used to send and receive service requests.
     * @param url The endpoint where to send service requests.
     * @param serviceVersion The version of the service to receive requests.
     * @param accountName The storage account name.
     * @param containerName The container name.
     * @param blobName The blob name.
     * @param snapshot The snapshot identifier for the blob, pass {@code null} to interact with the blob directly.
     * @param customerProvidedKey Customer provided key used during encryption of the blob's data on the server, pass
     * {@code null} to allow the service to use its own encryption.
     * @param encryptionScope Encryption scope used during encryption of the blob's data on the server, pass
     * {@code null} to allow the service to use its own encryption.
     * @param versionId The version identifier for the blob, pass {@code null} to interact with the latest blob version.
     */
    protected BlobAsyncClient(HttpPipeline pipeline, String url, BlobServiceVersion serviceVersion, String accountName,
                              String containerName, String blobName, String snapshot, CpkInfo customerProvidedKey,
                              EncryptionScope encryptionScope, String versionId) {
        super(pipeline, url, serviceVersion, accountName, containerName, blobName, snapshot, customerProvidedKey,
            encryptionScope, versionId);
    }

    /**
     * Creates a new {@link BlobAsyncClient} linked to the {@code snapshot} of this blob resource.
     *
     * @param snapshot the identifier for a specific snapshot of this blob
     * @return A {@link BlobAsyncClient} used to interact with the specific snapshot.
     */
    @Override
    public BlobAsyncClient getSnapshotClient(String snapshot) {
        return new BlobAsyncClient(getHttpPipeline(), getBlobUrl(), getServiceVersion(), getAccountName(),
            getContainerName(), getBlobName(), snapshot, getCustomerProvidedKey(), encryptionScope, getVersionId());
    }

    /**
     * Creates a new {@link BlobAsyncClient} linked to the {@code versionId} of this blob resource.
     *
     * @param versionId the identifier for a specific version of this blob,
     * pass {@code null} to interact with the latest blob version.
     * @return A {@link BlobAsyncClient} used to interact with the specific version.
     */
    @Override
    public BlobAsyncClient getVersionClient(String versionId) {
        return new BlobAsyncClient(getHttpPipeline(), getBlobUrl(), getServiceVersion(), getAccountName(),
            getContainerName(), getBlobName(), getSnapshotId(), getCustomerProvidedKey(), encryptionScope, versionId);
    }

    /**
     * Creates a new {@link AppendBlobAsyncClient} associated with this blob.
     *
     * @return A {@link AppendBlobAsyncClient} associated with this blob.
     */
    public AppendBlobAsyncClient getAppendBlobAsyncClient() {
        return prepareBuilder().buildAppendBlobAsyncClient();
    }

    /**
     * Creates a new {@link BlockBlobAsyncClient} associated with this blob.
     *
     * @return A {@link BlockBlobAsyncClient} associated with this blob.
     */
    public BlockBlobAsyncClient getBlockBlobAsyncClient() {
        return prepareBuilder().buildBlockBlobAsyncClient();
    }

    /**
     * Creates a new {@link PageBlobAsyncClient} associated with this blob.
     *
     * @return A {@link PageBlobAsyncClient} associated with this blob.
     */
    public PageBlobAsyncClient getPageBlobAsyncClient() {
        return prepareBuilder().buildPageBlobAsyncClient();
    }

    private SpecializedBlobClientBuilder prepareBuilder() {
        SpecializedBlobClientBuilder builder = new SpecializedBlobClientBuilder()
            .pipeline(getHttpPipeline())
            .endpoint(getBlobUrl())
            .snapshot(getSnapshotId())
            .serviceVersion(getServiceVersion());

        CpkInfo cpk = getCustomerProvidedKey();
        if (cpk != null) {
            builder.customerProvidedKey(new CustomerProvidedKey(cpk.getEncryptionKey()));
        }

        if (encryptionScope != null) {
            builder.encryptionScope(encryptionScope.getEncryptionScope());
        }

        return builder;
    }

    /**
     * Creates a new block blob. By default this method will not overwrite an existing blob.
     *

     * Updating an existing block blob overwrites any existing metadata on the blob. Partial updates are not supported
     * with this method; the content of the existing blob is overwritten with the new content. To perform a partial
     * update of a block blob's, use {@link BlockBlobAsyncClient#stageBlock(String, Flux, long) stageBlock} and {@link
     * BlockBlobAsyncClient#commitBlockList(List) commitBlockList}. For more information, see the
     * Azure Docs for Put Block and the
     * Azure Docs for Put Block List.
     *

     * The data passed need not support multiple subscriptions/be replayable as is required in other upload methods when
     * retries are enabled, and the length of the data need not be known in advance. Therefore, this method does
     * support uploading any arbitrary data source, including network streams. This behavior is possible because this
     * method will perform some internal buffering as configured by the blockSize and numBuffers parameters, so while
     * this method may offer additional convenience, it will not be as performant as other options, which should be
     * preferred when possible.
     *

     * Typically, the greater the number of buffers used, the greater the possible parallelism when transferring the
     * data. Larger buffers means we will have to stage fewer blocks and therefore require fewer IO operations. The
     * trade-offs between these values are context-dependent, so some experimentation may be required to optimize inputs
     * for a given scenario.
     *
     *
Code Samples

     *
     * {@codesnippet com.azure.storage.blob.BlobAsyncClient.upload#Flux-ParallelTransferOptions}
     *
     * @param data The data to write to the blob. Unlike other upload methods, this method does not require that the
     * {@code Flux} be replayable. In other words, it does not have to support multiple subscribers and is not expected
     * to produce the same values across subscriptions.
     * @param parallelTransferOptions {@link ParallelTransferOptions} used to configure buffered uploading.
     * @return A reactive response containing the information of the uploaded block blob.
     */
    public Mono<BlockBlobItem> upload(Flux<ByteBuffer> data, ParallelTransferOptions parallelTransferOptions) {
        try {
            return upload(data, parallelTransferOptions, false);
        } catch (RuntimeException ex) {
            return monoError(logger, ex);
        }
    }

    /**
     * Creates a new block blob, or updates the content of an existing block blob.
     *

     * Updating an existing block blob overwrites any existing metadata on the blob. Partial updates are not supported
     * with this method; the content of the existing blob is overwritten with the new content. To perform a partial
     * update of a block blob's, use {@link BlockBlobAsyncClient#stageBlock(String, Flux, long) stageBlock} and {@link
     * BlockBlobAsyncClient#commitBlockList(List) commitBlockList}. For more information, see the
     * Azure Docs for Put Block and the
     * Azure Docs for Put Block List.
     *

     * The data passed need not support multiple subscriptions/be replayable as is required in other upload methods when
     * retries are enabled, and the length of the data need not be known in advance. Therefore, this method does
     * support uploading any arbitrary data source, including network streams. This behavior is possible because this
     * method will perform some internal buffering as configured by the blockSize and numBuffers parameters, so while
     * this method may offer additional convenience, it will not be as performant as other options, which should be
     * preferred when possible.
     *

     * Typically, the greater the number of buffers used, the greater the possible parallelism when transferring the
     * data. Larger buffers means we will have to stage fewer blocks and therefore require fewer IO operations. The
     * trade-offs between these values are context-dependent, so some experimentation may be required to optimize inputs
     * for a given scenario.
     *
     *
Code Samples

     *
     * {@codesnippet com.azure.storage.blob.BlobAsyncClient.upload#Flux-ParallelTransferOptions-boolean}
     *
     * @param data The data to write to the blob. Unlike other upload methods, this method does not require that the
     * {@code Flux} be replayable. In other words, it does not have to support multiple subscribers and is not expected
     * to produce the same values across subscriptions.
     * @param parallelTransferOptions {@link ParallelTransferOptions} used to configure buffered uploading.
     * @param overwrite Whether or not to overwrite, should the blob already exist.
     * @return A reactive response containing the information of the uploaded block blob.
     */
    public Mono<BlockBlobItem> upload(Flux<ByteBuffer> data, ParallelTransferOptions parallelTransferOptions,
        boolean overwrite) {
        try {
            Mono<Void> overwriteCheck;
            BlobRequestConditions requestConditions;

            if (overwrite) {
                overwriteCheck = Mono.empty();
                requestConditions = null;
            } else {
                overwriteCheck = exists().flatMap(exists -> exists
                    ? monoError(logger, new IllegalArgumentException(Constants.BLOB_ALREADY_EXISTS))
                    : Mono.empty());
                requestConditions = new BlobRequestConditions().setIfNoneMatch(Constants.HeaderConstants.ETAG_WILDCARD);
            }

            return overwriteCheck
                .then(uploadWithResponse(data, parallelTransferOptions, null, null, null,
                    requestConditions)).flatMap(FluxUtil::toMono);
        } catch (RuntimeException ex) {
            return monoError(logger, ex);
        }
    }

    /**
     * Creates a new block blob, or updates the content of an existing block blob.
     *

     * Updating an existing block blob overwrites any existing metadata on the blob. Partial updates are not supported
     * with this method; the content of the existing blob is overwritten with the new content. To perform a partial
     * update of a block blob's, use {@link BlockBlobAsyncClient#stageBlock(String, Flux, long) stageBlock} and {@link
     * BlockBlobAsyncClient#commitBlockList(List) commitBlockList}. For more information, see the
     * Azure Docs for Put Block and the
     * Azure Docs for Put Block List.
     *

     * The data passed need not support multiple subscriptions/be replayable as is required in other upload methods when
     * retries are enabled, and the length of the data need not be known in advance. Therefore, this method does
     * support uploading any arbitrary data source, including network streams. This behavior is possible because this
     * method will perform some internal buffering as configured by the blockSize and numBuffers parameters, so while
     * this method may offer additional convenience, it will not be as performant as other options, which should be
     * preferred when possible.
     *

     * Typically, the greater the number of buffers used, the greater the possible parallelism when transferring the
     * data. Larger buffers means we will have to stage fewer blocks and therefore require fewer IO operations. The
     * trade-offs between these values are context-dependent, so some experimentation may be required to optimize inputs
     * for a given scenario.
     *

     * To avoid overwriting, pass "*" to {@link BlobRequestConditions#setIfNoneMatch(String)}.
     *
     *
Code Samples

     *
     * {@codesnippet com.azure.storage.blob.BlobAsyncClient.uploadWithResponse#Flux-ParallelTransferOptions-BlobHttpHeaders-Map-AccessTier-BlobRequestConditions}
     *
     *
Using Progress Reporting

     *
     * {@codesnippet com.azure.storage.blob.BlobAsyncClient.uploadWithResponse#Flux-ParallelTransferOptions-BlobHttpHeaders-Map-AccessTier-BlobRequestConditions.ProgressReporter}
     *
     * @param data The data to write to the blob. Unlike other upload methods, this method does not require that the
     * {@code Flux} be replayable. In other words, it does not have to support multiple subscribers and is not expected
     * to produce the same values across subscriptions.
     * @param parallelTransferOptions {@link ParallelTransferOptions} used to configure buffered uploading.
     * @param headers {@link BlobHttpHeaders}
     * @param metadata Metadata to associate with the blob.
     * @param tier {@link AccessTier} for the destination blob.
     * @param requestConditions {@link BlobRequestConditions}
     * @return A reactive response containing the information of the uploaded block blob.
     */
    public Mono<Response<BlockBlobItem>> uploadWithResponse(Flux<ByteBuffer> data,
        ParallelTransferOptions parallelTransferOptions, BlobHttpHeaders headers, Map<String, String> metadata,
        AccessTier tier, BlobRequestConditions requestConditions) {
        return this.uploadWithResponse(new BlobParallelUploadOptions(data)
            .setParallelTransferOptions(parallelTransferOptions).setHeaders(headers).setMetadata(metadata).setTier(tier)
            .setRequestConditions(requestConditions));
    }

    /**
     * Creates a new block blob, or updates the content of an existing block blob.
     *

     * Updating an existing block blob overwrites any existing metadata on the blob. Partial updates are not supported
     * with this method; the content of the existing blob is overwritten with the new content. To perform a partial
     * update of a block blob's, use {@link BlockBlobAsyncClient#stageBlock(String, Flux, long) stageBlock} and {@link
     * BlockBlobAsyncClient#commitBlockList(List) commitBlockList}. For more information, see the
     * Azure Docs for Put Block and the
     * Azure Docs for Put Block List.
     *

     * The data passed need not support multiple subscriptions/be replayable as is required in other upload methods when
     * retries are enabled, and the length of the data need not be known in advance. Therefore, this method does
     * support uploading any arbitrary data source, including network streams. This behavior is possible because this
     * method will perform some internal buffering as configured by the blockSize and numBuffers parameters, so while
     * this method may offer additional convenience, it will not be as performant as other options, which should be
     * preferred when possible.
     *

     * Typically, the greater the number of buffers used, the greater the possible parallelism when transferring the
     * data. Larger buffers means we will have to stage fewer blocks and therefore require fewer IO operations. The
     * trade-offs between these values are context-dependent, so some experimentation may be required to optimize inputs
     * for a given scenario.
     *

     * To avoid overwriting, pass "*" to {@link BlobRequestConditions#setIfNoneMatch(String)}.
     *
     *
Code Samples

     *
     * {@codesnippet com.azure.storage.blob.BlobAsyncClient.uploadWithResponse#BlobParallelUploadOptions}
     *
     *
Using Progress Reporting

     *
     * {@codesnippet com.azure.storage.blob.BlobAsyncClient.uploadWithResponse#BlobParallelUploadOptions}
     *
     * @param options {@link BlobParallelUploadOptions}. Unlike other upload methods, this method does not require that
     * the {@code Flux} be replayable. In other words, it does not have to support multiple subscribers and is not
     * expected to produce the same values across subscriptions.
     * @return A reactive response containing the information of the uploaded block blob.
     */
    public Mono<Response<BlockBlobItem>> uploadWithResponse(BlobParallelUploadOptions options) {
        try {
            StorageImplUtils.assertNotNull("options", options);

            final ParallelTransferOptions parallelTransferOptions =
                ModelHelper.populateAndApplyDefaults(options.getParallelTransferOptions());
            final BlobHttpHeaders headers = options.getHeaders();
            final Map<String, String> metadata = options.getMetadata();
            final Map<String, String> tags = options.getTags();
            final AccessTier tier = options.getTier();
            final BlobRequestConditions requestConditions = options.getRequestConditions() == null
                ? new BlobRequestConditions() : options.getRequestConditions();
            final boolean computeMd5 = options.isComputeMd5();

            BlockBlobAsyncClient blockBlobAsyncClient = getBlockBlobAsyncClient();

            Function<Flux<ByteBuffer>, Mono<Response<BlockBlobItem>>> uploadInChunksFunction = (stream) ->
                uploadInChunks(blockBlobAsyncClient, stream, parallelTransferOptions, headers, metadata, tags,
                    tier, requestConditions, computeMd5);

            BiFunction<Flux<ByteBuffer>, Long, Mono<Response<BlockBlobItem>>> uploadFullBlobFunction =
                (stream, length) -> uploadFullBlob(blockBlobAsyncClient, stream, length, parallelTransferOptions,
                    headers, metadata, tags, tier, requestConditions, computeMd5);

            Flux<ByteBuffer> data = options.getDataFlux() == null ? Utility.convertStreamToByteBuffer(
                options.getDataStream(), options.getLength(),
                // We can only buffer up to max int due to restrictions in ByteBuffer.
                (int) Math.min(Integer.MAX_VALUE, parallelTransferOptions.getBlockSizeLong()))
                : options.getDataFlux();
            return UploadUtils.uploadFullOrChunked(data, ModelHelper.wrapBlobOptions(parallelTransferOptions),
                uploadInChunksFunction, uploadFullBlobFunction);
        } catch (RuntimeException ex) {
            return monoError(logger, ex);
        }
    }

    private Mono<Response<BlockBlobItem>> uploadFullBlob(BlockBlobAsyncClient blockBlobAsyncClient,
        Flux<ByteBuffer> data, long length, ParallelTransferOptions parallelTransferOptions, BlobHttpHeaders headers,
        Map<String, String> metadata, Map<String, String> tags, AccessTier tier,
        BlobRequestConditions requestConditions, boolean computeMd5) {
        // Report progress as necessary.
        Flux<ByteBuffer> progressData = ProgressReporter.addProgressReporting(data,
            parallelTransferOptions.getProgressReceiver());

        return UploadUtils.computeMd5(progressData, computeMd5, logger)
            .map(fluxMd5Wrapper -> new BlockBlobSimpleUploadOptions(fluxMd5Wrapper.getData(), length)
                .setHeaders(headers)
                .setMetadata(metadata)
                .setTags(tags)
                .setTier(tier)
                .setRequestConditions(requestConditions)
                .setContentMd5(fluxMd5Wrapper.getMd5()))
            .flatMap(blockBlobAsyncClient::uploadWithResponse);
    }

    private Mono<Response<BlockBlobItem>> uploadInChunks(BlockBlobAsyncClient blockBlobAsyncClient,
        Flux<ByteBuffer> data, ParallelTransferOptions parallelTransferOptions, BlobHttpHeaders headers,
        Map<String, String> metadata, Map<String, String> tags, AccessTier tier,
        BlobRequestConditions requestConditions, boolean computeMd5) {
        // TODO: Sample/api reference
        // See ProgressReporter for an explanation on why this lock is necessary and why we use AtomicLong.
        AtomicLong totalProgress = new AtomicLong();
        Lock progressLock = new ReentrantLock();

        // Validation done in the constructor.
        /*
        We use maxConcurrency + 1 for the number of buffers because one buffer will typically be being filled while the
        others are being sent.
         */
        UploadBufferPool pool = new UploadBufferPool(parallelTransferOptions.getMaxConcurrency() + 1,
            parallelTransferOptions.getBlockSizeLong(), BlockBlobClient.MAX_STAGE_BLOCK_BYTES_LONG);

        Flux<ByteBuffer> chunkedSource = UploadUtils.chunkSource(data,
            ModelHelper.wrapBlobOptions(parallelTransferOptions));

        /*
         Write to the pool and upload the output.
         */
        return chunkedSource.concatMap(pool::write)
            .concatWith(Flux.defer(pool::flush))
            .flatMapSequential(bufferAggregator -> {
                // Report progress as necessary.
                Flux<ByteBuffer> progressData = ProgressReporter.addParallelProgressReporting(
                    bufferAggregator.asFlux(),
                    parallelTransferOptions.getProgressReceiver(),
                    progressLock,
                    totalProgress);

                final String blockId = Base64.getEncoder().encodeToString(UUID.randomUUID().toString().getBytes(UTF_8));
                return UploadUtils.computeMd5(progressData, computeMd5, logger)
                    .flatMap(fluxMd5Wrapper -> blockBlobAsyncClient.stageBlockWithResponse(blockId,
                        fluxMd5Wrapper.getData(), bufferAggregator.length(), fluxMd5Wrapper.getMd5(),
                        requestConditions.getLeaseId()))
                    // We only care about the stageBlock insofar as it was successful,
                    // but we need to collect the ids.
                    .map(x -> blockId)
                    .doFinally(x -> pool.returnBuffer(bufferAggregator))
                    .flux();
            }, parallelTransferOptions.getMaxConcurrency())
            .collect(Collectors.toList())
            .flatMap(ids ->
                blockBlobAsyncClient.commitBlockListWithResponse(new BlockBlobCommitBlockListOptions(ids)
                    .setHeaders(headers).setMetadata(metadata).setTags(tags).setTier(tier)
                        .setRequestConditions(requestConditions)));
    }

    /**
     * Creates a new block blob with the content of the specified file. By default this method will not overwrite an
     * existing blob.
     *
     *
Code Samples

     *
     * {@codesnippet com.azure.storage.blob.BlobAsyncClient.uploadFromFile#String}
     *
     * @param filePath Path to the upload file
     * @return An empty response
     * @throws UncheckedIOException If an I/O error occurs
     */
    public Mono<Void> uploadFromFile(String filePath) {
        try {
            return uploadFromFile(filePath, false);
        } catch (RuntimeException ex) {
            return monoError(logger, ex);
        }
    }

    /**
     * Creates a new block blob, or updates the content of an existing block blob, with the content of the specified
     * file.
     *
     *
Code Samples

     *
     * {@codesnippet com.azure.storage.blob.BlobAsyncClient.uploadFromFile#String-boolean}
     *
     * @param filePath Path to the upload file
     * @param overwrite Whether or not to overwrite, should the blob already exist.
     * @return An empty response
     * @throws UncheckedIOException If an I/O error occurs
     */
    public Mono<Void> uploadFromFile(String filePath, boolean overwrite) {
        try {
            Mono<Void> overwriteCheck = Mono.empty();
            BlobRequestConditions requestConditions = null;

            // Note that if the file will be uploaded using a putBlob, we also can skip the exists check.
            if (!overwrite) {
                if (UploadUtils.shouldUploadInChunks(filePath,
                    BlockBlobAsyncClient.MAX_UPLOAD_BLOB_BYTES_LONG, logger)) {
                    overwriteCheck = exists().flatMap(exists -> exists
                        ? monoError(logger, new IllegalArgumentException(Constants.BLOB_ALREADY_EXISTS))
                        : Mono.empty());
                }

                requestConditions = new BlobRequestConditions().setIfNoneMatch(Constants.HeaderConstants.ETAG_WILDCARD);
            }

            return overwriteCheck.then(uploadFromFile(filePath, null, null, null, null, requestConditions));
        } catch (RuntimeException ex) {
            return monoError(logger, ex);
        }
    }

    /**
     * Creates a new block blob, or updates the content of an existing block blob, with the content of the specified
     * file.
     *

     * To avoid overwriting, pass "*" to {@link BlobRequestConditions#setIfNoneMatch(String)}.
     *
     *
Code Samples

     *
     * {@codesnippet com.azure.storage.blob.BlobAsyncClient.uploadFromFile#String-ParallelTransferOptions-BlobHttpHeaders-Map-AccessTier-BlobRequestConditions}
     *
     * @param filePath Path to the upload file
     * @param parallelTransferOptions {@link ParallelTransferOptions} to use to upload from file. Number of parallel
     * transfers parameter is ignored.
     * @param headers {@link BlobHttpHeaders}
     * @param metadata Metadata to associate with the blob.
     * @param tier {@link AccessTier} for the destination blob.
     * @param requestConditions {@link BlobRequestConditions}
     * @return An empty response
     * @throws UncheckedIOException If an I/O error occurs
     */
    public Mono<Void> uploadFromFile(String filePath, ParallelTransferOptions parallelTransferOptions,
        BlobHttpHeaders headers, Map<String, String> metadata, AccessTier tier,
        BlobRequestConditions requestConditions) {
        return this.uploadFromFileWithResponse(new BlobUploadFromFileOptions(filePath)
            .setParallelTransferOptions(parallelTransferOptions).setHeaders(headers).setMetadata(metadata)
            .setTier(tier).setRequestConditions(requestConditions))
            .then();
    }

    /**
     * Creates a new block blob, or updates the content of an existing block blob, with the content of the specified
     * file.
     *

     * To avoid overwriting, pass "*" to {@link BlobRequestConditions#setIfNoneMatch(String)}.
     *
     *
Code Samples

     *
     * {@codesnippet com.azure.storage.blob.BlobAsyncClient.uploadFromFileWithResponse#BlobUploadFromFileOptions}
     *
     * @param options {@link BlobUploadFromFileOptions}
     * @return A reactive response containing the information of the uploaded block blob.
     * @throws UncheckedIOException If an I/O error occurs
     */
    public Mono<Response<BlockBlobItem>> uploadFromFileWithResponse(BlobUploadFromFileOptions options) {
        StorageImplUtils.assertNotNull("options", options);
        Long originalBlockSize = (options.getParallelTransferOptions() == null)
            ? null
            : options.getParallelTransferOptions().getBlockSizeLong();
        final ParallelTransferOptions finalParallelTransferOptions =
            ModelHelper.populateAndApplyDefaults(options.getParallelTransferOptions());
        try {
            return Mono.using(() -> UploadUtils.uploadFileResourceSupplier(options.getFilePath(), logger),
                channel -> {
                    try {
                        BlockBlobAsyncClient blockBlobAsyncClient = getBlockBlobAsyncClient();
                        long fileSize = channel.size();

                        // If the file is larger than 256MB chunk it and stage it as blocks.
                        if (UploadUtils.shouldUploadInChunks(options.getFilePath(),
                            finalParallelTransferOptions.getMaxSingleUploadSizeLong(), logger)) {
                            return uploadFileChunks(fileSize, finalParallelTransferOptions, originalBlockSize,
                                options.getHeaders(), options.getMetadata(), options.getTags(),
                                options.getTier(), options.getRequestConditions(), channel,
                                blockBlobAsyncClient);
                        } else {
                            // Otherwise we know it can be sent in a single request reducing network overhead.
                            Flux<ByteBuffer> data = FluxUtil.readFile(channel);
                            if (finalParallelTransferOptions.getProgressReceiver() != null) {
                                data = ProgressReporter.addProgressReporting(data,
                                    finalParallelTransferOptions.getProgressReceiver());
                            }
                            return blockBlobAsyncClient.uploadWithResponse(
                                new BlockBlobSimpleUploadOptions(data, fileSize).setHeaders(options.getHeaders())
                                    .setMetadata(options.getMetadata()).setTags(options.getTags())
                                    .setTier(options.getTier())
                                    .setRequestConditions(options.getRequestConditions()));
                        }
                    } catch (IOException ex) {
                        return Mono.error(ex);
                    }
                },
                channel ->
                UploadUtils.uploadFileCleanup(channel, logger));
        } catch (RuntimeException ex) {
            return monoError(logger, ex);
        }
    }

    private Mono<Response<BlockBlobItem>> uploadFileChunks(
        long fileSize, ParallelTransferOptions parallelTransferOptions,
        Long originalBlockSize, BlobHttpHeaders headers, Map<String, String> metadata, Map<String, String> tags,
        AccessTier tier, BlobRequestConditions requestConditions, AsynchronousFileChannel channel,
        BlockBlobAsyncClient client) {
        final BlobRequestConditions finalRequestConditions = (requestConditions == null)
            ? new BlobRequestConditions() : requestConditions;
        // parallelTransferOptions are finalized in the calling method.

        // See ProgressReporter for an explanation on why this lock is necessary and why we use AtomicLong.
        AtomicLong totalProgress = new AtomicLong();
        Lock progressLock = new ReentrantLock();

        final SortedMap<Long, String> blockIds = new TreeMap<>();
        return Flux.fromIterable(sliceFile(fileSize, originalBlockSize, parallelTransferOptions.getBlockSizeLong()))
            .flatMap(chunk -> {
                String blockId = getBlockID();
                blockIds.put(chunk.getOffset(), blockId);

                Flux<ByteBuffer> progressData = ProgressReporter.addParallelProgressReporting(
                    FluxUtil.readFile(channel, chunk.getOffset(), chunk.getCount()),
                    parallelTransferOptions.getProgressReceiver(), progressLock, totalProgress);

                return client.stageBlockWithResponse(blockId, progressData, chunk.getCount(), null,
                    finalRequestConditions.getLeaseId());
            }, parallelTransferOptions.getMaxConcurrency())
            .then(Mono.defer(() -> client.commitBlockListWithResponse(
                new BlockBlobCommitBlockListOptions(new ArrayList<>(blockIds.values()))
                    .setHeaders(headers).setMetadata(metadata).setTags(tags).setTier(tier)
                    .setRequestConditions(finalRequestConditions))));
    }

    /**
     * RESERVED FOR INTERNAL USE.
     *
     * Resource Supplier for UploadFile.
     *
     * @param filePath The path for the file
     * @return {@code AsynchronousFileChannel}
     * @throws UncheckedIOException an input output exception.
     * @deprecated due to refactoring code to be in the common storage library.
     */
    @Deprecated
    protected AsynchronousFileChannel uploadFileResourceSupplier(String filePath) {
        return UploadUtils.uploadFileResourceSupplier(filePath, logger);
    }

    private String getBlockID() {
        return Base64.getEncoder().encodeToString(UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8));
    }

    private List<BlobRange> sliceFile(long fileSize, Long originalBlockSize, long blockSize) {
        List<BlobRange> ranges = new ArrayList<>();
        if (fileSize > 100 * Constants.MB && originalBlockSize == null) {
            blockSize = BLOB_DEFAULT_HTBB_UPLOAD_BLOCK_SIZE;
        }
        for (long pos = 0; pos < fileSize; pos += blockSize) {
            long count = blockSize;
            if (pos + count > fileSize) {
                count = fileSize - pos;
            }
            ranges.add(new BlobRange(pos, count));
        }
        return ranges;
    }
}


text:
using System;
using System.Threading.Tasks;

namespace Passenger.Infrastructure.Services
{
    public interface IHandlerTaskRunner
    {
        IHandlerTask Run(Func<Task> runAsync);
    }
}

redpajama_set_name: RedPajamaGithub


text:
<?php

namespace tests\OPNsense\Base;

use OPNsense\Core\Config;

require_once 'BaseModel/TestModel.php';

class BaseModelTest extends \PHPUnit\Framework\TestCase
{
    private static $model = null;

    public function testResetConfig()
    {
        // reset version, force migrations
        if (
            !empty(Config::getInstance()->object()->tests) &&
            !empty(Config::getInstance()->object()->tests->OPNsense) &&
            !empty(Config::getInstance()->object()->tests->OPNsense->TestModel)
        ) {
            Config::getInstance()->object()->tests->OPNsense->TestModel['version'] = '0.0.0';
            Config::getInstance()->object()->tests->OPNsense->TestModel->general->FromEmail = "sample@example.com";
        }
        BaseModelTest::$model = new BaseModel\TestModel();
        $this->assertEquals((string)BaseModelTest::$model->general->FromEmail, 'sample@example.com');
    }

    /**
     * @depends testResetConfig
     */
    public function testCanBeCreated()
    {
        BaseModelTest::$model = new BaseModel\TestModel();
        $this->assertInstanceOf('tests\OPNsense\Base\BaseModel\TestModel', BaseModelTest::$model);
    }

    /**
     * @depends testCanBeCreated
     */
    public function testGeneralAvailable()
    {
        $this->assertNotNull(BaseModelTest::$model->general);
    }

    /**
     * @depends testCanBeCreated
     */
    public function testRunMigrations()
    {
        BaseModelTest::$model->runMigrations();
        // migration should have prefixed our default email address
        $this->assertEquals((string)BaseModelTest::$model->general->FromEmail, '100_001_sample@example.com');
    }

    /**
     * @depends testRunMigrations
     */
    public function testCanSetStringValue()
    {
        BaseModelTest::$model->general->FromEmail = "test@test.nl";
        $this->assertEquals(BaseModelTest::$model->general->FromEmail, "test@test.nl");
    }

    /**
     * @depends testRunMigrations
     */
    public function testCannotSetNonExistingField()
    {
        $this->expectException(\InvalidArgumentException::class);
        $this->expectExceptionMessage("FromEmailXXX not an attribute of general");
        BaseModelTest::$model->general->FromEmailXXX = "test@test.nl";
    }

    /**
     * @depends testRunMigrations
     */
    public function testCanAssignArrayType()
    {
        // purge test items (if any)
        foreach (BaseModelTest::$model->arraytypes->item->iterateItems() as $nodeid => $node) {
            BaseModelTest::$model->arraytypes->item->Del($nodeid);
        }
        // generate new items
        for ($i = 1; $i <= 10; $i++) {
            $node = BaseModelTest::$model->arraytypes->item->Add();
            $node->number = $i;
        }
        // flush to disk
        BaseModelTest::$model->serializeToConfig();
        Config::getInstance()->save();

        // load from disk
        Config::getInstance()->forceReload();
        BaseModelTest::$model = new BaseModel\TestModel();

        // read items, logically the sequence should be the same as the generated items
        $i = 1;
        foreach (BaseModelTest::$model->arraytypes->item->iterateItems() as $node) {
            $this->assertEquals($i, (string)$node->number);
            $i++;
        }
    }

    /**
     * @depends testCanAssignArrayType
     */
    public function testCanDeleteSpecificItem()
    {
        foreach (BaseModelTest::$model->arraytypes->item->iterateItems() as $nodeid => $node) {
            if ((string)$node->number == 5) {
                BaseModelTest::$model->arraytypes->item->Del($nodeid);
            }
        }
        // item with number 5 should be deleted
        foreach (BaseModelTest::$model->arraytypes->item->iterateItems() as $nodeid => $node) {
            $this->assertNotEquals((string)$node->number, 5);
        }
        // 9 items left
        $this->assertEquals(count(iterator_to_array(BaseModelTest::$model->arraytypes->item->iterateItems())), 9);
    }

    /**
     * @depends testCanAssignArrayType
     */
    public function testArrayIsKeydByUUID()
    {
        foreach (BaseModelTest::$model->arraytypes->item->iterateItems() as $nodeid => $node) {
            $this->assertCount(5, explode('-', $nodeid));
        }
    }

    /**
     * @depends testCanAssignArrayType
     */
    public function testValidationOk()
    {
        // nothing changed, valid config
        BaseModelTest::$model->serializeToConfig();
        $this->assertInstanceOf('tests\OPNsense\Base\BaseModel\TestModel', BaseModelTest::$model);
    }

    /**
     * @depends testCanAssignArrayType
     */
    public function testValidationNOK()
    {
        $this->expectException(\OPNsense\Phalcon\Filter\Validation\Exception::class);
        $this->expectExceptionMessage("not a valid number");
        // replace all numbers
        foreach (BaseModelTest::$model->arraytypes->item->iterateItems() as $nodeid => $node) {
            $node->number = "XXX";
        }
        BaseModelTest::$model->serializeToConfig();
    }

    /**
     * @depends testRunMigrations
     */
    public function testsetNodeByReferenceFound()
    {
        $this->assertEquals(BaseModelTest::$model->setNodeByReference('general.FromEmail', 'test@test.com'), true);
    }

    /**
     * @depends testRunMigrations
     */
    public function testsetNodeByReferenceNotFound()
    {
        $this->assertEquals(BaseModelTest::$model->setNodeByReference('general.FromEmailxx', 'test@test.com'), false);
    }

    /**
     * @depends testCanDeleteSpecificItem
     */
    public function testGenerateXML()
    {
        $xml = BaseModelTest::$model->toXML();
        $this->assertInstanceOf(\SimpleXMLElement::class, $xml);
        $this->assertNotEquals(count($xml->OPNsense), 0);
        $this->assertNotEquals(count($xml->OPNsense->TestModel), 0);
        $this->assertNotEquals(count($xml->OPNsense->TestModel->general), 0);
        // expect 9 detail items at this point
        $this->assertEquals(count($xml->OPNsense->TestModel->arraytypes->item), 9);
    }

    /**
     * @depends testCanDeleteSpecificItem
     */
    public function testSetNode()
    {
        $data = array();
        $i = 100;
        foreach (BaseModelTest::$model->arraytypes->item->iterateItems() as $nodeid => $node) {
            $data[$node->__reference] = $i;
            $i++;
        }
        foreach ($data as $key => $value) {
            $node = BaseModelTest::$model->getNodeByReference($key);
            $node->setNodes(array('number' => $value));
        }

        foreach (BaseModelTest::$model->arraytypes->item->iterateItems() as $nodeid => $node) {
            $this->assertGreaterThan(99, (string)$node->number);
        }
    }

    /**
     * @depends testCanDeleteSpecificItem
     */
    public function testGetNodes()
    {
        $data = BaseModelTest::$model->arraytypes->item->getNodes();
        $this->assertEquals(count($data), 9);
    }

    /**
     * @depends testGetNodes
     */
    public function testConstraintsNok()
    {
        $this->expectException(\OPNsense\Phalcon\Filter\Validation\Exception::class);
        $this->expectExceptionMessage("number should be unique");
        $count = 2;
        foreach (BaseModelTest::$model->arraytypes->item->iterateItems() as $nodeid => $node) {
            $count--;
            if ($count >= 0) {
                $node->number = 999;
            }
        }
        BaseModelTest::$model->serializeToConfig();
    }

    /**
     * @depends testConstraintsNok
     */
    public function testConstraintsOk()
    {
        $count = 1;
        foreach (BaseModelTest::$model->arraytypes->item->iterateItems() as $nodeid => $node) {
            $count++;
            $node->number = $count;
        }
        BaseModelTest::$model->serializeToConfig();
        $this->assertInstanceOf('tests\OPNsense\Base\BaseModel\TestModel', BaseModelTest::$model);
    }

    /**
     * @depends testRunMigrations
     */
    public function testAllOrNoneInitial()
    {
        BaseModelTest::$model->AllOrNone->value1 = "";
        BaseModelTest::$model->AllOrNone->value2 = "";
        BaseModelTest::$model->AllOrNone->value3 = "";
        BaseModelTest::$model->serializeToConfig();
        $this->assertEquals(Config::getInstance()->object()->tests->OPNsense->TestModel->AllOrNone->value1, '');
        $this->assertEquals(Config::getInstance()->object()->tests->OPNsense->TestModel->AllOrNone->value2, '');
        $this->assertEquals(Config::getInstance()->object()->tests->OPNsense->TestModel->AllOrNone->value3, '');
    }

    /**
     * @depends testAllOrNoneInitial
     */
    public function testAllOrNoneNok()
    {
        $this->expectException(\Exception::class);
        $this->expectExceptionMessage("All fields should contain data or none of them");
        BaseModelTest::$model->AllOrNone->value1 = "";
        BaseModelTest::$model->AllOrNone->value2 = "X";
        BaseModelTest::$model->AllOrNone->value3 = "";
        BaseModelTest::$model->serializeToConfig();
    }

    /**
     * @depends testAllOrNoneNok
     */
    public function testAllOrNoneOk()
    {
        BaseModelTest::$model->AllOrNone->value1 = "X1";
        BaseModelTest::$model->AllOrNone->value2 = "X2";
        BaseModelTest::$model->AllOrNone->value3 = "X3";
        BaseModelTest::$model->serializeToConfig();
        $this->assertEquals(Config::getInstance()->object()->tests->OPNsense->TestModel->AllOrNone->value1, "X1");
        $this->assertEquals(Config::getInstance()->object()->tests->OPNsense->TestModel->AllOrNone->value2, "X2");
        $this->assertEquals(Config::getInstance()->object()->tests->OPNsense->TestModel->AllOrNone->value3, "X3");
    }

    /**
     * @depends testRunMigrations
     */
    public function testSingleSelectInitial()
    {
        BaseModelTest::$model->SingleSelect->value1 = "";
        BaseModelTest::$model->SingleSelect->value2 = "";
        BaseModelTest::$model->SingleSelect->value3 = "";
        BaseModelTest::$model->serializeToConfig();
        $this->assertEquals(Config::getInstance()->object()->tests->OPNsense->TestModel->SingleSelect->value1, '');
        $this->assertEquals(Config::getInstance()->object()->tests->OPNsense->TestModel->SingleSelect->value2, '');
        $this->assertEquals(Config::getInstance()->object()->tests->OPNsense->TestModel->SingleSelect->value3, '');
    }

    /**
     * @depends testSingleSelectInitial
     */
    public function testSingleSelectNok()
    {
        $this->expectException(\Exception::class);
        $this->expectExceptionMessage("Only one option could be selected");
        BaseModelTest::$model->SingleSelect->value1 = "x";
        BaseModelTest::$model->SingleSelect->value2 = "x";
        BaseModelTest::$model->SingleSelect->value3 = "";
        BaseModelTest::$model->serializeToConfig();
    }

    /**
     * @depends testSingleSelectNok
     */
    public function testSingleSelectOk()
    {
        BaseModelTest::$model->SingleSelect->value1 = "";
        BaseModelTest::$model->SingleSelect->value2 = "x";
        BaseModelTest::$model->SingleSelect->value3 = "";
        BaseModelTest::$model->serializeToConfig();
        $this->assertEquals(Config::getInstance()->object()->tests->OPNsense->TestModel->SingleSelect->value1, '');
        $this->assertEquals(Config::getInstance()->object()->tests->OPNsense->TestModel->SingleSelect->value2, 'x');
        $this->assertEquals(Config::getInstance()->object()->tests->OPNsense->TestModel->SingleSelect->value3, '');
    }

    /**
     * @depends testRunMigrations
     */
    public function testDependConstraintInitial()
    {
        BaseModelTest::$model->DependConstraint->value1 = "0";
        BaseModelTest::$model->DependConstraint->value2 = "";
        BaseModelTest::$model->serializeToConfig();
        $this->assertEquals(Config::getInstance()->object()->tests->OPNsense->TestModel->DependConstraint->value1, "0");
        $this->assertEquals(
            Config::getInstance()->object()->tests->OPNsense->TestModel->DependConstraint->value2,
            ""
        );
    }

    /**
     * @depends testDependConstraintInitial
     */
    public function testDependConstraintNok()
    {
        $this->expectException(\Exception::class);
        $this->expectExceptionMessage("when value1 is enabled value2 is required");
        BaseModelTest::$model->DependConstraint->value1 = "1";
        BaseModelTest::$model->DependConstraint->value2 = "";
        BaseModelTest::$model->serializeToConfig();
        $this->assertEquals(Config::getInstance()->object()->tests->OPNsense->TestModel->DependConstraint->value1, "0");
    }

    /**
     * @depends testDependConstraintInitial
     */
    public function testDependConstraintOk1()
    {
        BaseModelTest::$model->DependConstraint->value1 = "1";
        BaseModelTest::$model->DependConstraint->value2 = "xxx";
        BaseModelTest::$model->serializeToConfig();
        $this->assertEquals(Config::getInstance()->object()->tests->OPNsense->TestModel->DependConstraint->value1, "1");
        $this->assertEquals(
            Config::getInstance()->object()->tests->OPNsense->TestModel->DependConstraint->value2,
            "xxx"
        );
    }

    /**
     * @depends testDependConstraintInitial
     */
    public function testDependConstraintOk2()
    {
        BaseModelTest::$model->DependConstraint->value1 = "0";
        BaseModelTest::$model->DependConstraint->value2 = "xxx";
        BaseModelTest::$model->serializeToConfig();
        $this->assertEquals(Config::getInstance()->object()->tests->OPNsense->TestModel->DependConstraint->value1, "0");
        $this->assertEquals(
            Config::getInstance()->object()->tests->OPNsense->TestModel->DependConstraint->value2,
            "xxx"
        );
    }
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<sem:triples uri="http://www.lds.org/vrl/geo-political/europe/croatia/dubrovnik-croatia" xmlns:sem="http://marklogic.com/semantics">
  <sem:triple>
    <sem:subject>http://www.lds.org/vrl/geo-political/europe/croatia/dubrovnik-croatia</sem:subject>
    <sem:predicate>http://www.w3.org/2004/02/skos/core#prefLabel</sem:predicate>
    <sem:object datatype="xsd:string" xml:lang="eng">Dubrovnik (Croatia)</sem:object>
  </sem:triple>
  <sem:triple>
    <sem:subject>http://www.lds.org/vrl/geo-political/europe/croatia/dubrovnik-croatia</sem:subject>
    <sem:predicate>http://www.w3.org/2004/02/skos/core#inScheme</sem:predicate>
    <sem:object datatype="sem:iri">http://www.lds.org/concept-scheme/vrl</sem:object>
  </sem:triple>
  <sem:triple>
    <sem:subject>http://www.lds.org/vrl/geo-political/europe/croatia/dubrovnik-croatia</sem:subject>
    <sem:predicate>http://www.lds.org/core#entityType</sem:predicate>
    <sem:object datatype="sem:iri">http://www.schema.org/Place</sem:object>
  </sem:triple>
</sem:triples>


text:
namespace dx
{
    class GameWindow;
    class SceneBase;
    class Game;
    class InputSystem;

    using SceneCreator = std::function<std::unique_ptr<SceneBase>(Game&)>;

    class SceneSwitcher
    {
      public:
        friend void RunGame(Game&, std::unique_ptr<GameWindow>, std::uint32_t);
        friend class Game;

        SceneSwitcher(Game& game);

        void AddSceneCreator(std::uint32_t index, SceneCreator creator);

        template<typename EnumT,
                 typename = std::enable_if_t<std::is_enum_v<EnumT>>>
        void AddSceneCreator(EnumT index, SceneCreator creator)
        {
            using type = std::underlying_type_t<EnumT>;
            static_assert(sizeof(type) < sizeof(std::uint32_t),
                          "The size of enum's underlying type should be "
                          "less than sizeof(std::uint32_t).");
            AddSceneCreator(static_cast<type>(index), std::move(creator));
        }

        // TODO: enum version.
        void WantToSwitchSceneTo(std::uint32_t index);

        SceneBase& MainScene() const { return *mainScene_; }

      private:
        void ReallySwitchToScene(Game& game, std::uint32_t index);
        void CheckAndSwitch();
        void Reset();

        std::unordered_map<std::uint32_t, SceneCreator> sceneCreators_;
        std::unique_ptr<SceneBase> mainScene_;
        std::optional<std::uint32_t> nextSceneIndex_;
        Game& game_;
    };

    struct UpdateArgs
    {
        Duration Delta;
    };

    class Game
    {
        friend void RunGame(Game&, std::unique_ptr<GameWindow>, std::uint32_t);

      public:
        Game(std::unique_ptr<GlobalGraphicsContext> globalGraphics,
             std::uint32_t fps);
        ~Game();

        WindowResizeEvent WindowResize;
        DpiChangedEvent DpiChanged;

        GameWindow& MainWindow() const { return *mainWindow_; }
        GlobalGraphicsContext& GlobalGraphics() { return *m_globalGraphics; }
        SceneSwitcher& Switcher() noexcept { return sceneSwitcher_; }
        const SceneSwitcher& Switcher() const noexcept
        {
            return sceneSwitcher_;
        }
        const InputSystem& GetInputSystem() const noexcept
        {
            return *m_inputSystem;
        }

      private:
        friend struct MessageDispatcher;

        void Run();
        void SetUp(std::unique_ptr<GameWindow> mainWindow);
        void UnpackMessage(WindowEventArgsPack event);
        void PrepareGraphicsForResizing(GameWindow* window, Size newSize);
        InputSystem& GetInputSystem() noexcept { return *m_inputSystem; }

        std::unique_ptr<GlobalGraphicsContext> m_globalGraphics;
        SceneSwitcher sceneSwitcher_;
        // TODO: only one window?
        std::unique_ptr<GameWindow> mainWindow_;
        std::unique_ptr<InputSystem> m_inputSystem;
        std::uint32_t fps_;
    };

    void RunGame(Game& game, std::unique_ptr<GameWindow> mainWindow,
                 std::uint32_t mainSceneIndex);
} // namespace dx


text:
@class XABGuardianHeaderView;
#pragma mark - 定义协议
@protocol XABGuardianHeaderViewDelegate <NSObject>

- (void)guardianHeaderViewDidSelectedHeader:(XABGuardianHeaderView *)header;

@end

#pragma mark - 定义接口

@interface XABGuardianHeaderView : UITableViewHeaderFooterView
// 定义代理
@property (weak, nonatomic) id <XABGuardianHeaderViewDelegate> guardianHeaderDelegate;

@property (strong, nonatomic) UILabel *labelStudent;
@property (strong, nonatomic) UILabel *labelTelephoto;
//
@property (assign, nonatomic) BOOL      isOpen;
// 标题栏分组
@property (assign, nonatomic) NSInteger section;

@end


text:
SlowScene::SlowScene(const Vector &backgroundColor, float spaceIoR)
	: Scene(backgroundColor, spaceIoR)
{
}

SlowScene::~SlowScene(void)
{
	while(!objectList.empty())
	{
		delete objectList.back();
		objectList.pop_back();
	}
	while(!lightSourceList.empty())
	{
		delete lightSourceList.back();
		lightSourceList.pop_back();
	}
}

void SlowScene::addObject(IntersectableObject *obj)
{
	objectList.push_back(obj);
}

void SlowScene::addLightSource(LightSource *light)
{
	lightSourceList.push_back(light);
}

IntersectableObject* SlowScene::hitObject(const Ray &r, float *distance) const
{
	*distance = efl::INF;
	int objectListSize = objectList.size();
	IntersectableObject *obj = NULL;

	for(int i = 0; i < objectListSize; ++i)
	{
		float t;
		if(objectList[i]->intersect(r, t))
			if(t < *distance)
			{
				*distance = t;
				obj = objectList[i];
			}
	}

	return obj;
}

Vector SlowScene::shade(const Ray &r, const Material *mat, const Vector &nhit, const Vector &phit) const
{
	Vector outColor(0.0f);

	int objectListSize = objectList.size();
	int lightSources = lightSourceList.size();
	for(int i = 0; i < lightSources; ++i)
	{
		float transmission(1.0f);
		Vector lightDirection = (lightSourceList[i]->position - phit).normalized();
		float tnear = (phit - lightSourceList[i]->position).length();

		float tmp;
		if(hitObject(Ray(phit + nhit * efl::bias, lightDirection), &tmp) != NULL && tmp < tnear)
			transmission = 0.0f;

		if(transmission > efl::ZERO)//shade
		{
			Vector lightIntensity = lightSourceList[i]->intensityAtPoint(phit);
			if(mat->diff > efl::ZERO)//diffuse
				outColor += efl::max<float>(0.0f, dotProduct(lightDirection, nhit))
				* lightIntensity * mat->color * mat->diff;
			if(mat->spec > efl::ZERO)//specular
			{
				Vector R = lightDirection - 2.0f * dotProduct(lightDirection, nhit) * nhit;
				float dot = dotProduct(r.direction , R.normalized());
				if (dot > 0)
				{
					float spec = efl::fastPow(dot, 32) * mat->spec;
					outColor += spec * lightIntensity * mat->color;
				}
			}
		}
	}
	return outColor;
}


text:
'use strict';

let chai = require('chai')
let expect = chai.expect
let Project = require('../app/project').Project
let NamesValidator = require('../app/names-validator').Validator
let ProjectsFactory = require('./projects-factory').ProjectsFactory

describe('NamesValidator', function() {
  it('checkDuplicateNames() should not throw error, because names are different', function() {
    let namesToProjectDirs = new Map()
    namesToProjectDirs.set('MdefToolkit', ['F:/A/'])
    namesToProjectDirs.set('MdefApplication', ['F:/B/'])

    let validator = new NamesValidator()
    expect(validator.checkDuplicateNames.bind(validator, namesToProjectDirs))
      .to.not.throw()
  })

  it('checkDuplicateNames() should check duplicate names and throw', function() {
    let namesToProjectDirs = new Map()
    namesToProjectDirs.set('MdefToolkit', ['F:/A/', 'F:/B/'])

    let validator = new NamesValidator()
    expect(validator.checkDuplicateNames.bind(validator, namesToProjectDirs))
      .to.throw()
  })

  it('checkNonEmptyNames() should not throw, because names are not empty', function() {
    let projects = ProjectsFactory.createProjectsWithDifferentNames()
    let validator = new NamesValidator()

    expect(validator.checkNonEmptyNames.bind(validator, projects))
      .to.not.throw()
  })

  it('checkNonEmptyNames() should throw, because some names are empty', function() {
    let projects = ProjectsFactory.createProjectsWithEmptyNames()
    let validator = new NamesValidator()

    expect(validator.checkNonEmptyNames.bind(validator, projects))
      .to.throw()
  })

  it('mapNamesToPaths() should map 1 to 1', function() {
    let projects = ProjectsFactory.createProjectsWithDifferentNames()
    let validator = new NamesValidator()
    let nameToProjectDirs = validator.mapNamesToPaths(projects)

    let reference = new Map()
    reference.set('MdefDataModel', ['F:/A'])
    reference.set('MdefXml', ['F:/B'])

    expect(nameToProjectDirs).to.deep.equal(reference)
  })

  it('mapNamesToPaths() should map 1 to 1 with duplicate names', function() {
    let projects = ProjectsFactory.createProjectsWithSameNames()
    let validator = new NamesValidator()
    let nameToProjectDirs = validator.mapNamesToPaths(projects)

    let reference = new Map()
    reference.set('MdefDataModel', ['F:/A/', 'F:/B/'])

    expect(nameToProjectDirs).to.deep.equal(reference)
  })
})


text:
package com.box.l10n.mojito.okapi.filters;

import net.sf.okapi.common.annotation.IAnnotation;

/**
 * Indicates if the processing to copy plural forms, need when importing po files with gettext
 * plural forms
 *
 * @author jaurambault
 */
public class CopyFormsOnImport implements IAnnotation {}


text:
package uk.co.drnaylor.minecraft.hammer.core.commands.parsers;

import uk.co.drnaylor.minecraft.hammer.core.HammerCore;
import uk.co.drnaylor.minecraft.hammer.core.wrappers.WrappedPlayer;

import java.util.ListIterator;
import java.util.Optional;

public class OnlinePlayerParser implements IParser<WrappedPlayer> {
    private final HammerCore core;

    public OnlinePlayerParser(HammerCore core) {
        this.core = core;
    }

    @Override
    public Optional<WrappedPlayer> parseArgument(ListIterator<String> stringIterator) throws ArgumentParseException {
        if (!stringIterator.hasNext()) {
            throw new ArgumentParseException("No player was specified");
        }

        String name = stringIterator.next();
        WrappedPlayer pl = core.getWrappedServer().getPlayer(name);
        if (pl == null || !pl.isOnline()) {
            throw new ArgumentParseException("The player " + name + " is not online!");
        }

        return Optional.of(pl);
    }

    @Override
    public void onFailedButOptional(ListIterator<String> stringListIterator) {
        stringListIterator.previous();
    }
}


text:
/**
 * This class is generated by jOOQ
 */
package io.cattle.platform.core.model.tables;

/**
 * This class is generated by jOOQ.
 */
@javax.annotation.Generated(value    = { "http://www.jooq.org", "3.3.0" },
                            comments = "This class is generated by jOOQ")
@java.lang.SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class DatabasechangeloglockTable extends org.jooq.impl.TableImpl<io.cattle.platform.core.model.tables.records.DatabasechangeloglockRecord> {

	private static final long serialVersionUID = 1759341827;

	/**
	 * The singleton instance of cattle.DATABASECHANGELOGLOCK
	 */
	public static final io.cattle.platform.core.model.tables.DatabasechangeloglockTable DATABASECHANGELOGLOCK = new io.cattle.platform.core.model.tables.DatabasechangeloglockTable();

	/**
	 * The class holding records for this type
	 */
	@Override
	public java.lang.Class<io.cattle.platform.core.model.tables.records.DatabasechangeloglockRecord> getRecordType() {
		return io.cattle.platform.core.model.tables.records.DatabasechangeloglockRecord.class;
	}

	/**
	 * The column cattle.DATABASECHANGELOGLOCK.ID.
	 */
	public final org.jooq.TableField<io.cattle.platform.core.model.tables.records.DatabasechangeloglockRecord, java.lang.Integer> ID = createField("ID", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");

	/**
	 * The column cattle.DATABASECHANGELOGLOCK.LOCKED.
	 */
	public final org.jooq.TableField<io.cattle.platform.core.model.tables.records.DatabasechangeloglockRecord, java.lang.Boolean> LOCKED = createField("LOCKED", org.jooq.impl.SQLDataType.BIT.nullable(false), this, "");

	/**
	 * The column cattle.DATABASECHANGELOGLOCK.LOCKGRANTED.
	 */
	public final org.jooq.TableField<io.cattle.platform.core.model.tables.records.DatabasechangeloglockRecord, java.util.Date> LOCKGRANTED = createField("LOCKGRANTED", org.jooq.impl.SQLDataType.TIMESTAMP.asConvertedDataType(new io.cattle.platform.db.jooq.converter.DateConverter()), this, "");

	/**
	 * The column cattle.DATABASECHANGELOGLOCK.LOCKEDBY.
	 */
	public final org.jooq.TableField<io.cattle.platform.core.model.tables.records.DatabasechangeloglockRecord, java.lang.String> LOCKEDBY = createField("LOCKEDBY", org.jooq.impl.SQLDataType.VARCHAR.length(255), this, "");

	/**
	 * Create a cattle.DATABASECHANGELOGLOCK table reference
	 */
	public DatabasechangeloglockTable() {
		this("DATABASECHANGELOGLOCK", null);
	}

	/**
	 * Create an aliased cattle.DATABASECHANGELOGLOCK table reference
	 */
	public DatabasechangeloglockTable(java.lang.String alias) {
		this(alias, io.cattle.platform.core.model.tables.DatabasechangeloglockTable.DATABASECHANGELOGLOCK);
	}

	private DatabasechangeloglockTable(java.lang.String alias, org.jooq.Table<io.cattle.platform.core.model.tables.records.DatabasechangeloglockRecord> aliased) {
		this(alias, aliased, null);
	}

	private DatabasechangeloglockTable(java.lang.String alias, org.jooq.Table<io.cattle.platform.core.model.tables.records.DatabasechangeloglockRecord> aliased, org.jooq.Field<?>[] parameters) {
		super(alias, io.cattle.platform.core.model.CattleTable.CATTLE, aliased, parameters, "");
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public org.jooq.UniqueKey<io.cattle.platform.core.model.tables.records.DatabasechangeloglockRecord> getPrimaryKey() {
		return io.cattle.platform.core.model.Keys.KEY_DATABASECHANGELOGLOCK_PRIMARY;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public java.util.List<org.jooq.UniqueKey<io.cattle.platform.core.model.tables.records.DatabasechangeloglockRecord>> getKeys() {
		return java.util.Arrays.<org.jooq.UniqueKey<io.cattle.platform.core.model.tables.records.DatabasechangeloglockRecord>>asList(io.cattle.platform.core.model.Keys.KEY_DATABASECHANGELOGLOCK_PRIMARY);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public io.cattle.platform.core.model.tables.DatabasechangeloglockTable as(java.lang.String alias) {
		return new io.cattle.platform.core.model.tables.DatabasechangeloglockTable(alias, this);
	}

	/**
	 * Rename this table
	 */
	public io.cattle.platform.core.model.tables.DatabasechangeloglockTable rename(java.lang.String name) {
		return new io.cattle.platform.core.model.tables.DatabasechangeloglockTable(name, null);
	}
}


text:
<?php
namespace Altair\Tests\Structure\Stack;

trait _echo
{
    public function testEcho()
    {
        $this->assertInstanceToString($this->getInstance());
    }
}


text:
import ShareYourSystem as SYS

#Init
MyGetList=SYS.GetList()

#print
print('MyGetList is ')
print(MyGetList)

#Init
MyGetList=SYS.GetList(
	#ListVariable
	'MyInt',
	#GetterVariable
	{'MyInt':4}
)

#print
print('MyGetList is ')
print(MyGetList)

#Init
MyGetList=SYS.GetList([0,2],['hello','bonjour','allo'])

#print
print('MyGetList is ')
print(MyGetList)

#Init
MyGetList=SYS.GetList(['rrr',3])

#print
print('MyGetList is ')
print(MyGetList)

#Init
MyGetList=SYS.GetList(['GetterClass'],SYS)

#print
print('MyGetList is ')
print(MyGetList)

#Init
MyGetList=SYS.GetList('GetterClass',SYS)

#print
print('MyGetList is ')
print(MyGetList)

#Init
MyGetList=SYS.GetList(None,SYS)

#print
print('MyGetList is ')
print(MyGetList)

#Init
MyGetList=SYS.GetList([
		{'GetSortInt':3},
		{'GetSortInt':1}
	])

#print
print('MyGetList is ')
print(MyGetList)


text:
<?xml version="1.0" encoding="UTF-8"?>
<ldswebml type="image" uri="/media-library/images/gospel-art/new-testament#resurrected-christ-39608" xml:lang="eng" locale="eng" status="publish" xmlns:its="http://www.w3.org/2005/11/its">
  <search-meta>
      <uri-title its:translate="no">resurrected-christ-39608</uri-title>
      <source>resurrected-christ-39608</source>
      <publication-type its:translate="no">image</publication-type>
      <media-type its:translate="no">image</media-type>
      <publication value="ldsorg">LDS.org</publication>
      <publication-date value="2012-07-02">2012-07-02</publication-date>
      <title>Jesus Shows His Wounds</title>
      <description>Jesus Shows His Wounds (Gospel Art Book [2009], no. 60) - Luke 24:33–43; John 20:19–20</description>
      <collections>
          <collection its:translate="no">global-search</collection>
          <collection its:translate="no">media</collection>
          <collection its:translate="no">images</collection>
      </collections>
      <subjects>
          <subject>New Testament</subject>
          <subject>Art</subject>
          <subject>Jesus Christ</subject>
          <subject>Resurrection</subject>
          <subject>Apostles</subject>
          <subject>Hands</subject>
          <subject>Gospel Art Kit</subject>
      </subjects>
  </search-meta>
  <no-search>
      <path>http://media.ldscdn.org/images/media-library/gospel-art/new-testament/resurrected-christ-39608-gallery.jpg</path>
      <images>
          http://media.ldscdn.org/images/media-library/gospel-art/new-testament/resurrected-christ-39608-thumbnail.jpg
      </images>
          <download-urls>
              <download-url>
                  Mobile
                  <size>368 KB</size>
                  <path>http://media.ldscdn.org/images/media-library/gospel-art/new-testament/resurrected-christ-39608-mobile.jpg</path>
              </download-url>
              <download-url>
                  Tablet
                  <size>507 KB</size>
                  <path>http://media.ldscdn.org/images/media-library/gospel-art/new-testament/resurrected-christ-39608-tablet.jpg</path>
              </download-url>
              <download-url>
                  Print
                  <size>1.2 MB</size>
                  <path>http://media.ldscdn.org/images/media-library/gospel-art/new-testament/resurrected-christ-39608-print.jpg</path>
              </download-url>
              <download-url>
                  Wallpaper
                  <size>2.1 MB</size>
                  <path>http://media.ldscdn.org/images/media-library/gospel-art/new-testament/resurrected-christ-39608-wallpaper.jpg</path>
              </download-url>
          </download-urls>
  </no-search>
</ldswebml>


text:
package com.textocat.textokit.morph.opencorpora.resource;

import com.google.common.collect.*;
import com.textocat.textokit.morph.dictionary.resource.GramModel;
import com.textocat.textokit.morph.dictionary.resource.MorphDictionary;
import com.textocat.textokit.morph.model.Lemma;
import com.textocat.textokit.morph.model.LemmaLinkType;
import com.textocat.textokit.morph.model.Wordform;
import org.apache.commons.lang3.event.EventListenerSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.Serializable;
import java.util.BitSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.google.common.collect.ImmutableMap.copyOf;
import static com.google.common.collect.Tables.unmodifiableTable;

/**
 * @author Rinat Gareev
 */
public class MorphDictionaryImpl implements Serializable, MorphDictionary {

    private static final long serialVersionUID = -5575575933753079146L;
    private static final Logger log = LoggerFactory.getLogger(MorphDictionaryImpl.class);

    // meta fields
    private String version;
    private String revision;
    //
    private GramModel gramModel;
    //
    private Map<Integer, Lemma> lemmaMap = Maps.newHashMap();
    private Map<Short, LemmaLinkType> lemmaLinkTypeMap = Maps.newHashMap();
    // <from, to, type>
    private Table<Integer, Integer, LemmaLinkType> lemmaLinkTable = TreeBasedTable.create();

    private Map<BitSet, BitSet> uniqWordformGrammemsMap = Maps.newHashMap();
    private Map<BitSet, BitSet> uniqLemmaGrammemsMap = Maps.newHashMap();

    private WordformTST wfByString = new WordformTST();
    // set of complete tags (lex + wordform) seen in stored wordforms
    private Set<BitSet> tagset = Sets.newHashSet();

    private transient WordformPredictor wfPredictor;

    // state mark
    private transient boolean complete = false;

    private transient EventListenerSupport<MorphDictionaryListener> listeners = EventListenerSupport
            .create(MorphDictionaryListener.class);

    @Override
    public GramModel getGramModel() {
        return gramModel;
    }

    public void setGramModel(GramModel gramModel) {
        if (this.gramModel != null) {
            throw new UnsupportedOperationException("Can't change a grammatical model");
        }
        this.gramModel = gramModel;
        // fire event
        listeners.fire().onGramModelSet(this);
    }

    public void addListener(MorphDictionaryListener listener) {
        listeners.addListener(listener);
    }

    public void removeListener(MorphDictionaryListener listener) {
        listeners.removeListener(listener);
    }

    public void setWfPredictor(WordformPredictor wfPredictor) {
        this.wfPredictor = wfPredictor;
    }

    @Override
    public List<Wordform> getEntries(String str) {
        WordformTSTSearchResult result = wfByString.getLongestPrefixMatch(str);
        if (result.isMatchExact())
            return Lists.newArrayList(result);
        else if (wfPredictor != null) {
            return ImmutableList.copyOf(wfPredictor.predict(str, result));
        } else {
            // wfPredictor is not set
            return ImmutableList.of();
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getVersion() {
        return version;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getRevision() {
        return revision;
    }

    @Override
    public synchronized void addLemma(Lemma l) {
        l = l.cloneWithGrammems(internLemmaGrammems(l.getGrammems()));
        if (lemmaMap.put(l.getId(), l) != null) {
            throw new IllegalStateException(String.format(
                    "Duplicate lemma id - %s", l.getId()));
        }
    }

    @Override
    public int getLemmaMaxId() {
        int max = Integer.MIN_VALUE;
        for (Integer curId : lemmaMap.keySet()) {
            if (curId == null) {
                continue;
            }
            if (curId > max) {
                max = curId;
            }
        }
        return max;
    }

    public void addLemmaLinkType(LemmaLinkType linkType) {
        if (lemmaLinkTypeMap.put(linkType.getId(), linkType) != null) {
            throw new IllegalStateException(String.format(
                    "Duplicate lemma link type - %s", linkType.getId()));
        }
    }

    private transient int invalidLinkCounter = 0;

    public void addLemmaLink(int from, int to, short linkTypeId) {
        if (!lemmaMap.containsKey(from)) {
            invalidLinkCounter++;
            return;
        }
        if (!lemmaMap.containsKey(to)) {
            invalidLinkCounter++;
            return;
        }
        LemmaLinkType linkType = getLemmaLinkType(linkTypeId);
        if (linkType == null) {
            noLemmaLinkType(linkTypeId);
        }
        if (lemmaLinkTable.put(from, to, linkType) != null) {
            log.warn("More than one links exist between lemmas {} and {}", to, from);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public LemmaLinkType getLemmaLinkType(short id) {
        return lemmaLinkTypeMap.get(id);
    }

    @Override
    public Lemma getLemma(int lemmaId) {
        Lemma result = lemmaMap.get(lemmaId);
        if (result == null) {
            throw new IllegalStateException(String.format(
                    "No lemma with id = %s", lemmaId));
        }
        return result;
    }

    @Override
    public boolean containsGramSet(BitSet tag) {
        return tagset.contains(tag);
    }

    @Override
    public Map<Integer, LemmaLinkType> getLemmaOutlinks(int lemmaId) {
        return lemmaLinkTable.row(lemmaId);
    }

    @Override
    public Map<Integer, LemmaLinkType> getLemmaInlinks(int lemmaId) {
        return lemmaLinkTable.column(lemmaId);
    }

    public void addWordform(String text, Wordform wf) {
        wf = wf.cloneWithGrammems(internWordformGrammems(wf.getGrammems()));
        wfByString.put(text, wf);
        // add complete tag
        BitSet tag = wf.getGrammems();
        tag.or(getLemma(wf.getLemmaId()).getGrammems());
        tagset.add(tag);
        // fire event
        listeners.fire().onWordformAdded(this, text, wf);
    }

    @Override
    protected void finalize() throws Throwable {
        // TODO remove
        log.info("{}#finalize...", this);
    }

    void complete() {
        if (complete) {
            throw new IllegalStateException();
        }
        log.info("Completing dictionary. Valid lemma links: {}, invalid links: {}",
                lemmaLinkTable.size(), invalidLinkCounter);
        log.info("Unique wordform grammem bitsets count: {}", uniqWordformGrammemsMap.size());
        log.info("Unique lemma grammem bitsets count: {}", uniqLemmaGrammemsMap.size());
        log.info("Unique tag bitset count: {}", tagset.size());
        makeUnmodifiable();
        //		uniqGrammemsMap = null;
        complete = true;
    }

    void setVersion(String version) {
        this.version = version;
    }

    void setRevision(String revision) {
        this.revision = revision;
    }

    @SuppressWarnings("unused")
    private void noLemma(int id) {
        throw new IllegalStateException(String.format(
                "Lemma with id = %s is not registered", id));
    }

    private void noLemmaLinkType(int id) {
        throw new IllegalStateException(String.format(
                "Lemma link type with id = %s is not registered", id));
    }

    private void makeUnmodifiable() {
        //	lemmaMap = unmodifiableMap(lemmaMap);
        // ??? tagset
        lemmaLinkTypeMap = copyOf(lemmaLinkTypeMap);
        lemmaLinkTable = unmodifiableTable(lemmaLinkTable);
    }

    private void readObject(java.io.ObjectInputStream in)
            throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        complete = true;
    }

    private BitSet internWordformGrammems(BitSet grammems) {
        if (uniqWordformGrammemsMap.containsKey(grammems)) {
            return uniqWordformGrammemsMap.get(grammems);
        } else {
            uniqWordformGrammemsMap.put(grammems, grammems);
            return grammems;
        }
    }

    private BitSet internLemmaGrammems(BitSet grammems) {
        if (uniqLemmaGrammemsMap.containsKey(grammems)) {
            return uniqLemmaGrammemsMap.get(grammems);
        } else {
            uniqLemmaGrammemsMap.put(grammems, grammems);
            return grammems;
        }
    }
}


text:
#ifndef _ANNEXB_H_
#define _ANNEXB_H_

#include "nalucommon.h"

int WriteAnnexbNALU (NALU_t *n);
void CloseAnnexbFile();
void OpenAnnexbFile (char *Filename);

#endif //_ANNEXB_H_


text:
{{ popupFields.title }}

        {{ popupFields.message }}

      <button class="btn-event btn-no-icon" type="button" (click)="closeWindow(true)">{{ popupFields.action }}</button>
      <button class="btn-event btn-no-icon" (click)="closeWindow(false)" type="button">{{ popupFields.abort }}</button>


text:
<!doctype html>

	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600,700" rel="stylesheet">
	<link rel="stylesheet" href="css/reset.css">
	<link rel="stylesheet" href="css/style.css">

	<title>Add to Cart Interaction | CodyHouse</title>

Add to Cart Interaction

	Add To Cart

		Cart

0

0

Cart

				Item removed. Undo

				Checkout - $0

Product Name

				$25.99

					Delete

						Qty

							<select id="cd-product-'+ productId +'" name="quantity">
								<option value="1">1</option>
								<option value="2">2</option>

							</select>


text:
class Rule:
    """
    Rule object holds actions and the resulting action of the
    synchronous execution of the actions. Types of the actions can be
    either unique identifiers (like unique integer id) or Action
    objects of model.py library (where __eq__ is implemented so that
    two actions are equal even if they are represented by two distinct
    objects --- this is needed when _enabled method is used).
    """

    def __init__(self,list_of_acts,resulting_act):
        """Initialise with list of actions that are executed
        synchronously and an action that is the result of the
        execution.
        """
        self.setSynchronousActions(list_of_acts)
        self.setResult(resulting_act)

    def __str__(self):
        return str(self.__syncacts)+" -> "+str(self.__result)

    def setSynchronousActions(self,list_of_acts):
        self.__syncacts=list_of_acts

    def setResult(self,resulting_act):
        self.__result=resulting_act

    def getSynchronousActions(self):
        return self.__syncacts

    def getResult(self):
        return self.__result

    def _enabled(self,list_of_acts):
        """Assume that every action in the list_of_acts can be
        executed. If the rule specifies a synchronous execution that
        can be applied in this situation (that is, self.__syncacts is
        a subset of list_of_acts), the function returns True. All
        indexes in the pair are global acts. Otherwise False is
        returned."""

        # Types of items in self.__syncacts and list_of_acts is
        # cruisal here! "(self.__syncacts[i] in list_of_acts)" must
        # work!

        for req_act in self.__syncacts:
            if not req_act in list_of_acts:
                return False
        return True

class RuleList(list):
    """List of Rule objects (do not use for any other datatype)"""

    def enabled(self,list_of_acts):
        """Returns the list of Rule-objects that are enabled when all
        actions in the list_of_acts can be executed."""
        return [ rule
                 for rule in list.__iter__(self)
                 if rule._enabled(list_of_acts)
                 ]


text:
import pytest

base_file_suids = [("/test_file", "0o4644")]

@pytest.mark.parametrize("path, suid", base_file_suids)
def test_file_suids(analyzed_data, path, suid):
    data = analyzed_data("suids")
    base = data["image"]["imagedata"]["analysis_report"]["file_suids"]["files.suids"][
        "base"
    ]
    assert base[path] == suid


text:
<?php

	$GLOBALS['errorMessages'] = array(
			"mail" => array(
					"duplicate" => "Oops, ya te suscribiste ! (o alguien se suscribió en tu nombre... que miedo)"
				),
			"defaultError" => "Hubo un error, y no es tu culpa. Inténtalo de nuevo más tarde."
		);

/**
 * Simple function to connect to the database
 * @author Daniel Bolívar <daniel.bolivar@icloud.com>
 * @return Object mysqli connection object
 */
	function connectToDb()
	{
		// Test Database Info
		//$mysqli=mysqli_connect("localhost", "root", "root", "elede");
		// Actual Database info (can't post that on github)
		$mysqli=mysqli_connect("hostname", "username", "password", "dbname");
		// Check connection
		if (mysqli_connect_errno()) {
		  return "Failed to connect to MySQL: " . mysqli_connect_error();
		} else
		{
			return $mysqli;
		}
	}

/**
 * Helper function for closing the database
 * @author Daniel Bolívar <daniel.bolivar@icloud.com>
 * @param  object $stmt
 * @param  object $mysqli
 * @return void
 */
	function closeDb($stmt, $mysqli)
	{
		$stmt->close();
		mysqli_close($mysqli);
	}

/**
 * Gets called when all projects need to be fetched. Used in the portfolio section
 * @author Daniel Bolívar <daniel.bolivar@icloud.com>
 * @return json Json object with all the necessary information on the project
 */
	function getProjects() {
		$mysqli = connectToDb();
		$stmt = $mysqli->prepare("SELECT id, thumb_title, seo_link, thumb_image FROM projects");
		$stmt->execute();
		$stmt->bind_result($sId, $sThumbTitle, $sSeoLink, $sThumbImage);
		$aProjects = array();

		while($stmt->fetch())
		{
			$aTemp = array(
				"id" 			=> $sId,
				"thumb_title" 	=> $sThumbTitle,
				"seo_link"		=> $sSeoLink,
				"thumb_image" 	=> $sThumbImage
			);
		array_push($aProjects, $aTemp);
		}
		closeDb($stmt, $mysqli);
		return json_encode($aProjects);
	}

/**
 * Function for fetching a single project
 * @author Daniel Bolívar <daniel.bolivar@icloud.com>
 * @param  String $sExperimentName Name of the project
 * @return json                  Json object with all necessary info on the project
 */
	function getProject($sExperimentName) {
		$mysqli = connectToDb();
		$stmt = $mysqli->prepare("SELECT title, subtitle, hero_image, video, text_1, text_2, text_3, images_1, images_2, website_url, behance_url, facebook_url FROM projects WHERE seo_link = ?");
		$stmt->bind_param('s', $sExperimentName);
		$stmt->execute();
		$stmt->bind_result($sTitle, $sSubtitle, $sHeroImage, $sVideo, $sTextOne, $sTextTwo, $sTextThree, $sImagesOne, $sImagesTwo, $sWebsiteUrl, $sBehanceUrl, $sFacebookUrl);
		$aProject = array();
		$stmt->store_result();
		while($stmt->fetch())
		{
			$aTemp = array(
				"title"			=> $sTitle,
				"subtitle"		=> $sSubtitle,
				"hero_image"	=> $sHeroImage,
				"video"			=> $sVideo,
				"text_1"		=> utf8_encode($sTextOne),
				"text_2"		=> utf8_encode($sTextTwo),
				"text_3"		=> utf8_encode($sTextThree),
				"images_1"		=> $sImagesOne,
				"images_2"		=> $sImagesTwo,
				"website_url"	=> $sWebsiteUrl,
				"facebook_url"	=> $sFacebookUrl,
				"behance_url"	=> $sBehanceUrl
			);
			$aProject = $aTemp;
		}
		if($stmt->num_rows == 0)
		{
			return false;
		}
		foreach ($aProject as $key => $value) {
			if($value == null)
			{
				unset($aProject[$key]);
			}
		}
		if(isset($aProject["images_1"]))
		{
			$aProject["images_1"] = explode("_", $aProject["images_1"]);
		}
		if(isset($aProject["images_2"]))
		{
			$aProject["images_2"] = explode("_", $aProject["images_2"]);
		}
		return json_encode($aProject);
	}


text:
require 'helper'

class TestPostingClient < Test::Unit::TestCase
  should "test single posting creation and deletion" do
    keys = []
    client = PostingClient.new
    posting = Posting.new(
      :source => "3TAPS",
      :heading => "Svitla posting",
      :location => "ZZZ",
      :category => "ZZZZ",
      :timestamp => Time.now
    )
    response = client.create_posting(posting)
    assert_equal Array, response.class
    assert_equal CreateResponse, response.first.class
    assert_nil response.first.error
    posting_key = response.first.post_key
    p posting_key
#    posting.heading = "Svitla posting +++#{rand(100)}+++"
#    posting.postKey = posting_key
#    posting.body = "posting"
#   # sleep(50)
#    response = client.update_posting(posting)
#    p response
#    assert_equal true, response.success
#
#    keys << posting_key
#
#    posting = Posting.new(
#      :source => "3TAPS",
#      :heading => "Svitla posting",
#      :location => "ZZZ",
#      :category => "ZZZZ",
#      :timestamp => Time.now
#    )
#    response = client.create_posting(posting)
#    assert_equal Array, response.class
#    assert_equal CreateResponse, response.first.class
#    assert_nil response.first.error
#    posting_key = response.first.post_key
#    keys << posting_key
    p "waiting while indexed by server"
    sleep(10)
    response = client.delete_posting(posting_key)
    assert_equal DeleteResponse, response.class
    assert_equal true, response.success
  end

  should "test multiple postings creation and deletion" do
    client = PostingClient.new
    posting1 = Posting.new(
      :source => "3TAPS",
      :heading => "Svitla posting1",
      :location => "ZZZ",
      :category => "ZZZZ",
      :timestamp => Time.now
    )
    posting2 = Posting.new(
      :source => "3TAPS",
      :heading => "Svitla posting2",
      :location => "ZZZ",
      :category => "ZZZZ"
    )
    response = client.create_posting([posting1, posting2])
    p response
    assert_equal Array, response.class
    assert_equal CreateResponse, response.first.class
    assert_nil response.first.error
    p "waiting while indexed by server"
    sleep(15)
    posting_key = response[0].post_key
    posting1.postKey = posting_key
    posting_key = response[1].post_key
    posting2.postKey = posting_key
    posting1.body = "posting1"
    posting2.body = "posting2"
    response = client.update_posting([posting1, posting2])
    assert_equal true, response.success

    keys = [posting1.postKey, posting2.postKey]
    response = client.delete_posting(keys)
    assert_equal DeleteResponse, response.class
    assert_equal true, response.success
  end

  should "test posting retrieval" do
    client = PostingClient.new
    posting = client.get_posting("BLQ7YJD")
    assert_equal Posting, posting.class
    assert_equal "BLQ7YJD", posting.postKey
  end

  should "test posting deletion" do
    client = PostingClient.new
    result = client.delete_posting('post_key')
    assert_equal DeleteResponse, result.class
  end
end


text:
"""
aliyunauth.cms
~~~~~~~~~~~~~~

This module contains the authentication handlers for Ali Cms Service
"""

from . import sign_ver_1_0

class CmsAuth(sign_ver_1_0.AuthBase):
    """Attach Aliyun Rds Authentication to the given request

    :param access_key: the access_key of your ecs account
    :param secret_key: the secret_key of your ecs account
    :param response_format: (optional) response format [`xml`/`json`(default)]
    :param ram: (optional) resource access managment string (default None)

    Usage::

        >>> import requests
        >>> from aliyunauth import CmsAuth
        >>> req = requests.get(
        ...     "https://metrics.aliyuncs.com",
        ...     params=dict(
        ...         Action="DescribeMetricDatum",
        ...         Namespace="acs/ecs",
        ...         MetricName="vm.MemoryUtilization",
        ...         StartTime="2015-05-15T00:00:00Z",
        ...         Dimensions=json.dumps(dict(instanceId="instance-id"))
        ...     ),
        ...     auth=CmsAuth("access-key", "secret-key")
        ... )
        <Response [200]>

    """
    PARAMS_MAP = dict(TimeStamp="Timestamp")
    SERVICE = "cms"
    VERSION = "2015-04-20"