text:
#include "tls/s2n_async_pkey.h"

#include "crypto/s2n_hash.h"
#include "crypto/s2n_signature.h"
#include "error/s2n_errno.h"
#include "api/s2n.h"
#include "tls/s2n_connection.h"
#include "tls/s2n_handshake.h"
#include "utils/s2n_blob.h"
#include "utils/s2n_mem.h"
#include "utils/s2n_result.h"
#include "utils/s2n_safety.h"

struct s2n_async_pkey_decrypt_data {
    s2n_async_pkey_decrypt_complete on_complete;
    struct s2n_blob                 encrypted;
    struct s2n_blob                 decrypted;
    unsigned                        rsa_failed : 1;
};

struct s2n_async_pkey_sign_data {
    s2n_async_pkey_sign_complete on_complete;
    struct s2n_hash_state        digest;
    s2n_signature_algorithm      sig_alg;
    struct s2n_blob              signature;
};

struct s2n_async_pkey_op {
    s2n_async_pkey_op_type type;
    struct s2n_connection *conn;
    s2n_async_pkey_validation_mode validation_mode;
    unsigned               complete : 1;
    unsigned               applied : 1;
    union {
        struct s2n_async_pkey_decrypt_data decrypt;
        struct s2n_async_pkey_sign_data    sign;
    } op;
};

struct s2n_async_pkey_op_actions {
    S2N_RESULT (*perform)(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey);
    S2N_RESULT (*apply)(struct s2n_async_pkey_op *op, struct s2n_connection *conn);
    S2N_RESULT (*get_input_size)(struct s2n_async_pkey_op *op, uint32_t *data_len);
    S2N_RESULT (*get_input)(struct s2n_async_pkey_op *op, uint8_t *data, uint32_t data_len);
    S2N_RESULT (*set_output)(struct s2n_async_pkey_op *op, const uint8_t *data, uint32_t data_len);
    S2N_RESULT (*free)(struct s2n_async_pkey_op *op);
};

static S2N_RESULT s2n_async_get_actions(s2n_async_pkey_op_type type, const struct s2n_async_pkey_op_actions **actions);

static S2N_RESULT s2n_async_pkey_op_allocate(struct s2n_async_pkey_op **op);

static S2N_RESULT s2n_async_pkey_sign_async(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
                                            struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete);
static S2N_RESULT s2n_async_pkey_sign_sync(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
                                           struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete);

static S2N_RESULT s2n_async_pkey_decrypt_async(struct s2n_connection *conn, struct s2n_blob *encrypted,
                                               struct s2n_blob *               init_decrypted,
                                               s2n_async_pkey_decrypt_complete on_complete);
static S2N_RESULT s2n_async_pkey_decrypt_sync(struct s2n_connection *conn, struct s2n_blob *encrypted,
                                              struct s2n_blob *               init_decrypted,
                                              s2n_async_pkey_decrypt_complete on_complete);

static S2N_RESULT s2n_async_pkey_decrypt_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey);
static S2N_RESULT s2n_async_pkey_decrypt_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn);
static S2N_RESULT s2n_async_pkey_get_input_size_decrypt(struct s2n_async_pkey_op *op, uint32_t *data_len);
static S2N_RESULT s2n_async_pkey_get_input_decrypt(struct s2n_async_pkey_op *op, uint8_t *data, uint32_t data_len);
static S2N_RESULT s2n_async_pkey_op_set_output_decrypt(struct s2n_async_pkey_op *op, const uint8_t *data, uint32_t data_len);
static S2N_RESULT s2n_async_pkey_decrypt_free(struct s2n_async_pkey_op *op);

static S2N_RESULT s2n_async_pkey_sign_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey);
static S2N_RESULT s2n_async_pkey_sign_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn);
static S2N_RESULT s2n_async_pkey_get_input_size_sign(struct s2n_async_pkey_op *op, uint32_t *data_len);
static S2N_RESULT s2n_async_pkey_get_input_sign(struct s2n_async_pkey_op *op, uint8_t *data, uint32_t data_len);
static S2N_RESULT s2n_async_pkey_op_set_output_sign(struct s2n_async_pkey_op *op, const uint8_t *data, uint32_t data_len);
static S2N_RESULT s2n_async_pkey_sign_free(struct s2n_async_pkey_op *op);

static const struct s2n_async_pkey_op_actions s2n_async_pkey_decrypt_op = { .perform = &s2n_async_pkey_decrypt_perform,
                                                                            .apply   = &s2n_async_pkey_decrypt_apply,
                                                                            .get_input_size   = &s2n_async_pkey_get_input_size_decrypt,
                                                                            .get_input   = &s2n_async_pkey_get_input_decrypt,
                                                                            .set_output   = &s2n_async_pkey_op_set_output_decrypt,
                                                                            .free    = &s2n_async_pkey_decrypt_free };

static const struct s2n_async_pkey_op_actions s2n_async_pkey_sign_op = { .perform = &s2n_async_pkey_sign_perform,
                                                                         .apply   = &s2n_async_pkey_sign_apply,
                                                                         .get_input_size   = &s2n_async_pkey_get_input_size_sign,
                                                                         .get_input   = &s2n_async_pkey_get_input_sign,
                                                                         .set_output  = &s2n_async_pkey_op_set_output_sign,
                                                                         .free    = &s2n_async_pkey_sign_free };

DEFINE_POINTER_CLEANUP_FUNC(struct s2n_async_pkey_op *, s2n_async_pkey_op_free);

static S2N_RESULT s2n_async_get_actions(s2n_async_pkey_op_type type, const struct s2n_async_pkey_op_actions **actions)
{
    RESULT_ENSURE_REF(actions);

    switch (type) {
        case S2N_ASYNC_DECRYPT:
            *actions = &s2n_async_pkey_decrypt_op;
            return S2N_RESULT_OK;
        case S2N_ASYNC_SIGN:
            *actions = &s2n_async_pkey_sign_op;
            return S2N_RESULT_OK;
            /* No default for compiler warnings */
    }

    return S2N_RESULT_ERROR;
}

static S2N_RESULT s2n_async_pkey_op_allocate(struct s2n_async_pkey_op **op)
{
    RESULT_ENSURE_REF(op);
    RESULT_ENSURE(*op == NULL, S2N_ERR_SAFETY);

    /* allocate memory */
    DEFER_CLEANUP(struct s2n_blob mem = {0}, s2n_free);
    RESULT_GUARD_POSIX(s2n_alloc(&mem, sizeof(struct s2n_async_pkey_op)));
    RESULT_GUARD_POSIX(s2n_blob_zero(&mem));

    *op = (void *) mem.data;
    if (s2n_blob_init(&mem, NULL, 0) != S2N_SUCCESS) {
        *op = NULL;
        return S2N_RESULT_ERROR;
    }
    return S2N_RESULT_OK;
}

S2N_RESULT s2n_async_pkey_decrypt(struct s2n_connection *conn, struct s2n_blob *encrypted,
                                  struct s2n_blob *init_decrypted, s2n_async_pkey_decrypt_complete on_complete)
{
    RESULT_ENSURE_REF(conn);
    RESULT_ENSURE_REF(encrypted);
    RESULT_ENSURE_REF(init_decrypted);
    RESULT_ENSURE_REF(on_complete);

    if (conn->config->async_pkey_cb) {
        RESULT_GUARD(s2n_async_pkey_decrypt_async(conn, encrypted, init_decrypted, on_complete));
    } else {
        RESULT_GUARD(s2n_async_pkey_decrypt_sync(conn, encrypted, init_decrypted, on_complete));
    }

    return S2N_RESULT_OK;
}

S2N_RESULT s2n_async_cb_execute(struct s2n_connection *conn, struct s2n_async_pkey_op **owned_op)
{
    RESULT_ENSURE_REF(conn);
    RESULT_ENSURE_REF(owned_op);
    RESULT_ENSURE(conn->handshake.async_state == S2N_ASYNC_NOT_INVOKED, S2N_ERR_ASYNC_MORE_THAN_ONE);

    /* The callback now owns the operation, meaning we can't free it.
     * Wipe our version and pass a copy to the callback.
     */
    struct s2n_async_pkey_op *unowned_op = *owned_op;
    ZERO_TO_DISABLE_DEFER_CLEANUP(*owned_op);

    conn->handshake.async_state = S2N_ASYNC_INVOKED;
    RESULT_ENSURE(conn->config->async_pkey_cb(conn, unowned_op) == S2N_SUCCESS, S2N_ERR_ASYNC_CALLBACK_FAILED);

    /*
     * If the callback already completed the operation, continue.
     * Otherwise, we need to block s2n_negotiate and wait for the operation to complete.
     */
    if (conn->handshake.async_state == S2N_ASYNC_COMPLETE) {
        return S2N_RESULT_OK;
    }
    RESULT_BAIL(S2N_ERR_ASYNC_BLOCKED);
}

S2N_RESULT s2n_async_pkey_decrypt_async(struct s2n_connection *conn, struct s2n_blob *encrypted,
                                        struct s2n_blob *init_decrypted, s2n_async_pkey_decrypt_complete on_complete)
{
    RESULT_ENSURE_REF(conn);
    RESULT_ENSURE_REF(encrypted);
    RESULT_ENSURE_REF(init_decrypted);
    RESULT_ENSURE_REF(on_complete);

    DEFER_CLEANUP(struct s2n_async_pkey_op *op = NULL, s2n_async_pkey_op_free_pointer);
    RESULT_GUARD(s2n_async_pkey_op_allocate(&op));

    op->type = S2N_ASYNC_DECRYPT;
    op->conn = conn;
    op->validation_mode = conn->config->async_pkey_validation_mode;

    struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;
    decrypt->on_complete                        = on_complete;

    RESULT_GUARD_POSIX(s2n_dup(encrypted, &decrypt->encrypted));
    RESULT_GUARD_POSIX(s2n_dup(init_decrypted, &decrypt->decrypted));

    RESULT_GUARD(s2n_async_cb_execute(conn, &op));
    return S2N_RESULT_OK;
}

S2N_RESULT s2n_async_pkey_decrypt_sync(struct s2n_connection *conn, struct s2n_blob *encrypted,
                                       struct s2n_blob *init_decrypted, s2n_async_pkey_decrypt_complete on_complete)
{
    RESULT_ENSURE_REF(conn);
    RESULT_ENSURE_REF(encrypted);
    RESULT_ENSURE_REF(init_decrypted);
    RESULT_ENSURE_REF(on_complete);

    const struct s2n_pkey *pkey = conn->handshake_params.our_chain_and_key->private_key;

    bool rsa_failed = s2n_pkey_decrypt(pkey, encrypted, init_decrypted) != S2N_SUCCESS;
    RESULT_GUARD_POSIX(on_complete(conn, rsa_failed, init_decrypted));

    return S2N_RESULT_OK;
}

S2N_RESULT s2n_async_pkey_sign(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
                               struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete)
{
    RESULT_ENSURE_REF(conn);
    RESULT_ENSURE_REF(digest);
    RESULT_ENSURE_REF(on_complete);

    if (conn->config->async_pkey_cb) {
        RESULT_GUARD(s2n_async_pkey_sign_async(conn, sig_alg, digest, on_complete));
    } else {
        RESULT_GUARD(s2n_async_pkey_sign_sync(conn, sig_alg, digest, on_complete));
    }

    return S2N_RESULT_OK;
}

S2N_RESULT s2n_async_pkey_sign_async(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
                                     struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete)
{
    RESULT_ENSURE_REF(conn);
    RESULT_ENSURE_REF(digest);
    RESULT_ENSURE_REF(on_complete);

    DEFER_CLEANUP(struct s2n_async_pkey_op *op = NULL, s2n_async_pkey_op_free_pointer);
    RESULT_GUARD(s2n_async_pkey_op_allocate(&op));

    op->type = S2N_ASYNC_SIGN;
    op->conn = conn;
    op->validation_mode = conn->config->async_pkey_validation_mode;

    struct s2n_async_pkey_sign_data *sign = &op->op.sign;
    sign->on_complete                     = on_complete;
    sign->sig_alg                         = sig_alg;

    RESULT_GUARD_POSIX(s2n_hash_new(&sign->digest));
    RESULT_GUARD_POSIX(s2n_hash_copy(&sign->digest, digest));

    RESULT_GUARD(s2n_async_cb_execute(conn, &op));
    return S2N_RESULT_OK;
}

S2N_RESULT s2n_async_pkey_sign_sync(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
                                    struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete)
{
    RESULT_ENSURE_REF(conn);
    RESULT_ENSURE_REF(digest);
    RESULT_ENSURE_REF(on_complete);

    const struct s2n_pkey *pkey = conn->handshake_params.our_chain_and_key->private_key;
    DEFER_CLEANUP(struct s2n_blob signed_content = { 0 }, s2n_free);

    uint32_t maximum_signature_length = 0;
    RESULT_GUARD(s2n_pkey_size(pkey, &maximum_signature_length));
    RESULT_GUARD_POSIX(s2n_alloc(&signed_content, maximum_signature_length));

    RESULT_GUARD_POSIX(s2n_pkey_sign(pkey, sig_alg, digest, &signed_content));

    RESULT_GUARD_POSIX(on_complete(conn, &signed_content));

    return S2N_RESULT_OK;
}

int s2n_async_pkey_op_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *key)
{
    POSIX_ENSURE_REF(op);
    POSIX_ENSURE_REF(key);
    POSIX_ENSURE(!op->complete, S2N_ERR_ASYNC_ALREADY_PERFORMED);

    const struct s2n_async_pkey_op_actions *actions = NULL;
    POSIX_GUARD_RESULT(s2n_async_get_actions(op->type, &actions));
    POSIX_ENSURE_REF(actions);

    POSIX_GUARD_RESULT(actions->perform(op, key));

    op->complete = true;

    return S2N_SUCCESS;
}

int s2n_async_pkey_op_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn)
{
    POSIX_ENSURE_REF(op);
    POSIX_ENSURE_REF(conn);
    POSIX_ENSURE(op->complete, S2N_ERR_ASYNC_NOT_PERFORMED);
    POSIX_ENSURE(!op->applied, S2N_ERR_ASYNC_ALREADY_APPLIED);
    /* We could have just used op->conn and removed a conn argument, but we want caller
     * to be explicit about connection it wants to resume. Plus this gives more
     * protections in cases if caller frees connection object and then tries to resume
     * the connection. */
    POSIX_ENSURE(op->conn == conn, S2N_ERR_ASYNC_WRONG_CONNECTION);
    POSIX_ENSURE(conn->handshake.async_state == S2N_ASYNC_INVOKED, S2N_ERR_ASYNC_WRONG_CONNECTION);

    const struct s2n_async_pkey_op_actions *actions = NULL;
    POSIX_GUARD_RESULT(s2n_async_get_actions(op->type, &actions));
    POSIX_ENSURE_REF(actions);

    POSIX_GUARD_RESULT(actions->apply(op, conn));

    op->applied                 = true;
    conn->handshake.async_state = S2N_ASYNC_COMPLETE;

    /* Free up the decrypt/sign structs to avoid storing secrets for too long */
    POSIX_GUARD_RESULT(actions->free(op));

    return S2N_SUCCESS;
}

int s2n_async_pkey_op_free(struct s2n_async_pkey_op *op)
{
    POSIX_ENSURE_REF(op);
    const struct s2n_async_pkey_op_actions *actions = NULL;
    POSIX_GUARD_RESULT(s2n_async_get_actions(op->type, &actions));
    POSIX_ENSURE_REF(actions);

    /* If applied the decrypt/sign structs were released in apply call */
    if (!op->applied) { POSIX_GUARD_RESULT(actions->free(op)); }

    POSIX_GUARD(s2n_free_object(( uint8_t ** )&op, sizeof(struct s2n_async_pkey_op)));

    return S2N_SUCCESS;
}

S2N_RESULT s2n_async_pkey_decrypt_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey)
{
    RESULT_ENSURE_REF(op);
    RESULT_ENSURE_REF(pkey);

    struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;

    decrypt->rsa_failed = s2n_pkey_decrypt(pkey, &decrypt->encrypted, &decrypt->decrypted) != S2N_SUCCESS;

    return S2N_RESULT_OK;
}

S2N_RESULT s2n_async_pkey_decrypt_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn)
{
    RESULT_ENSURE_REF(op);
    RESULT_ENSURE_REF(conn);

    struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;

    RESULT_GUARD_POSIX(decrypt->on_complete(conn, decrypt->rsa_failed, &decrypt->decrypted));

    return S2N_RESULT_OK;
}

S2N_RESULT s2n_async_pkey_decrypt_free(struct s2n_async_pkey_op *op)
{
    RESULT_ENSURE_REF(op);

    struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;

    RESULT_GUARD_POSIX(s2n_blob_zero(&decrypt->decrypted));
    RESULT_GUARD_POSIX(s2n_blob_zero(&decrypt->encrypted));
    RESULT_GUARD_POSIX(s2n_free(&decrypt->decrypted));
    RESULT_GUARD_POSIX(s2n_free(&decrypt->encrypted));

    return S2N_RESULT_OK;
}

S2N_RESULT s2n_async_pkey_sign_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey)
{
    RESULT_ENSURE_REF(op);
    RESULT_ENSURE_REF(op->conn);
    RESULT_ENSURE_REF(op->conn->config);
    RESULT_ENSURE_REF(pkey);

    struct s2n_async_pkey_sign_data *sign = &op->op.sign;

    uint32_t maximum_signature_length = 0;
    RESULT_GUARD(s2n_pkey_size(pkey, &maximum_signature_length));
    RESULT_GUARD_POSIX(s2n_alloc(&sign->signature, maximum_signature_length));

    /* If validation mode is S2N_ASYNC_PKEY_VALIDATION_STRICT
     * then use local hash copy to sign the signature */
    if (op->validation_mode == S2N_ASYNC_PKEY_VALIDATION_STRICT) {
        DEFER_CLEANUP(struct s2n_hash_state hash_state_copy, s2n_hash_free);
        RESULT_GUARD_POSIX(s2n_hash_new(&hash_state_copy));
        RESULT_GUARD_POSIX(s2n_hash_copy(&hash_state_copy, &sign->digest));

        RESULT_GUARD_POSIX(s2n_pkey_sign(pkey, sign->sig_alg, &hash_state_copy, &sign->signature));
    } else {
        RESULT_GUARD_POSIX(s2n_pkey_sign(pkey, sign->sig_alg, &sign->digest, &sign->signature));
    }

    return S2N_RESULT_OK;
}

S2N_RESULT s2n_async_pkey_sign_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn)
{
    RESULT_ENSURE_REF(op);
    RESULT_ENSURE_REF(conn);

    struct s2n_async_pkey_sign_data *sign = &op->op.sign;

    /* Perform signature validation only if validation feature is opt in */
    if (op->validation_mode == S2N_ASYNC_PKEY_VALIDATION_STRICT) {
        RESULT_GUARD(s2n_async_pkey_verify_signature(conn, sign->sig_alg, &sign->digest, &sign->signature));
    }

    RESULT_GUARD_POSIX(sign->on_complete(conn, &sign->signature));

    return S2N_RESULT_OK;
}

S2N_RESULT s2n_async_pkey_verify_signature(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
                                    struct s2n_hash_state *digest, struct s2n_blob *signature) {
    RESULT_ENSURE_REF(conn);
    RESULT_ENSURE_REF(conn->handshake_params.our_chain_and_key);
    RESULT_ENSURE_REF(digest);
    RESULT_ENSURE_REF(signature);

    /* Parse public key for the cert */
    DEFER_CLEANUP(struct s2n_pkey public_key = {0}, s2n_pkey_free);
    s2n_pkey_type pkey_type = S2N_PKEY_TYPE_UNKNOWN;
    RESULT_GUARD_POSIX(s2n_asn1der_to_public_key_and_type(&public_key, &pkey_type,
                                                &conn->handshake_params.our_chain_and_key->cert_chain->head->raw));
    RESULT_ENSURE(s2n_pkey_verify(&public_key, sig_alg, digest, signature) == S2N_SUCCESS, S2N_ERR_VERIFY_SIGNATURE);

    return S2N_RESULT_OK;
}

S2N_RESULT s2n_async_pkey_sign_free(struct s2n_async_pkey_op *op)
{
    RESULT_ENSURE_REF(op);

    struct s2n_async_pkey_sign_data *sign = &op->op.sign;

    RESULT_GUARD_POSIX(s2n_hash_free(&sign->digest));
    RESULT_GUARD_POSIX(s2n_free(&sign->signature));

    return S2N_RESULT_OK;
}

int s2n_async_pkey_op_set_validation_mode(struct s2n_async_pkey_op *op, s2n_async_pkey_validation_mode mode)
{
    POSIX_ENSURE_REF(op);

    switch(mode) {
        case S2N_ASYNC_PKEY_VALIDATION_FAST:
        case S2N_ASYNC_PKEY_VALIDATION_STRICT:
            op->validation_mode = mode;
            return S2N_SUCCESS;
    }

    POSIX_BAIL(S2N_ERR_INVALID_ARGUMENT);
}

int s2n_async_pkey_op_get_op_type(struct s2n_async_pkey_op *op, s2n_async_pkey_op_type *type)
{
    POSIX_ENSURE_REF(op);
    POSIX_ENSURE_REF(type);

    *type = op->type;

    return S2N_SUCCESS;
}

int s2n_async_pkey_op_get_input_size(struct s2n_async_pkey_op *op, uint32_t *data_len)
{
    POSIX_ENSURE_REF(op);
    POSIX_ENSURE_REF(data_len);

    const struct s2n_async_pkey_op_actions *actions = NULL;
    POSIX_GUARD_RESULT(s2n_async_get_actions(op->type, &actions));
    POSIX_ENSURE_REF(actions);

    POSIX_GUARD_RESULT(actions->get_input_size(op, data_len));

    return S2N_SUCCESS;
}

static S2N_RESULT s2n_async_pkey_get_input_size_decrypt(struct s2n_async_pkey_op *op, uint32_t *data_len)
{
    RESULT_ENSURE_REF(op);
    RESULT_ENSURE_REF(data_len);

    struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;
    struct s2n_blob *in = &decrypt->encrypted;

    *data_len = in->size;
    return S2N_RESULT_OK;
}

static S2N_RESULT s2n_async_pkey_get_input_size_sign(struct s2n_async_pkey_op *op, uint32_t *data_len)
{
    RESULT_ENSURE_REF(op);
    RESULT_ENSURE_REF(data_len);

    struct s2n_async_pkey_sign_data *sign = &op->op.sign;
    struct s2n_hash_state *digest = &sign->digest;

    uint8_t digest_length = 0;
    RESULT_GUARD_POSIX(s2n_hash_digest_size(digest->alg, &digest_length));

    *data_len = digest_length;

    return S2N_RESULT_OK;
}

int s2n_async_pkey_op_get_input(struct s2n_async_pkey_op *op, uint8_t *data, uint32_t data_len)
{
    POSIX_ENSURE_REF(op);
    POSIX_ENSURE_REF(data);

    const struct s2n_async_pkey_op_actions *actions = NULL;
    POSIX_GUARD_RESULT(s2n_async_get_actions(op->type, &actions));
    POSIX_ENSURE_REF(actions);

    POSIX_GUARD_RESULT(actions->get_input(op, data, data_len));

    return S2N_SUCCESS;
}

static S2N_RESULT s2n_async_pkey_get_input_decrypt(struct s2n_async_pkey_op *op, uint8_t *data, uint32_t data_len)
{
    RESULT_ENSURE_REF(op);
    RESULT_ENSURE_REF(data);

    struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;
    struct s2n_blob *in = &decrypt->encrypted;

    RESULT_ENSURE_LTE(in->size, data_len);

    RESULT_CHECKED_MEMCPY(data, in->data, in->size);

    return S2N_RESULT_OK;
}

static S2N_RESULT s2n_async_pkey_get_input_sign(struct s2n_async_pkey_op *op, uint8_t *data, uint32_t data_len)
{
    RESULT_ENSURE_REF(op);
    RESULT_ENSURE_REF(data);

    struct s2n_async_pkey_sign_data *sign = &op->op.sign;

    DEFER_CLEANUP(struct s2n_hash_state digest_copy = { 0 }, s2n_hash_free);
    RESULT_GUARD_POSIX(s2n_hash_new(&digest_copy));
    RESULT_GUARD_POSIX(s2n_hash_copy(&digest_copy, &sign->digest));

    uint8_t digest_length = 0;

    RESULT_GUARD_POSIX(s2n_hash_digest_size(digest_copy.alg, &digest_length));

    RESULT_ENSURE_LTE(digest_length, data_len);
    RESULT_GUARD_POSIX(s2n_hash_digest(&digest_copy, data, digest_length));

    return S2N_RESULT_OK;
}

int s2n_async_pkey_op_set_output(struct s2n_async_pkey_op *op, const uint8_t *data, uint32_t data_len)
{
    POSIX_ENSURE_REF(op);
    POSIX_ENSURE_REF(data);

    const struct s2n_async_pkey_op_actions *actions = NULL;
    POSIX_GUARD_RESULT(s2n_async_get_actions(op->type, &actions));
    POSIX_ENSURE_REF(actions);

    POSIX_GUARD_RESULT(actions->set_output(op, data, data_len));
    op->complete = true;

    return S2N_SUCCESS;
}

static S2N_RESULT s2n_async_pkey_op_set_output_decrypt(struct s2n_async_pkey_op *op, const uint8_t *data, uint32_t data_len)
{
    RESULT_ENSURE_REF(op);
    RESULT_ENSURE_REF(data);

    struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;
    struct s2n_blob *out = &decrypt->decrypted;

    RESULT_GUARD_POSIX(s2n_realloc(out, data_len));
    RESULT_CHECKED_MEMCPY(out->data, data, data_len);

    return S2N_RESULT_OK;
}

static S2N_RESULT s2n_async_pkey_op_set_output_sign(struct s2n_async_pkey_op *op, const uint8_t *data, uint32_t data_len)
{
    RESULT_ENSURE_REF(op);
    RESULT_ENSURE_REF(data);

    struct s2n_async_pkey_sign_data *sign = &op->op.sign;
    struct s2n_blob *sigcopy = &sign->signature;

    RESULT_GUARD_POSIX(s2n_realloc(sigcopy, data_len));
    RESULT_CHECKED_MEMCPY(sigcopy->data, data, data_len);

    return S2N_RESULT_OK;
}

redpajama_set_name: RedPajamaGithub


text:
<?php

namespace MWSimple\Bundle\ForoBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

/**
 * GrupoType form.
 * @author Nombre Apellido <name@gmail.com>
 */
class GrupoType extends AbstractType
{

    private $subjectInterface;

    public function __Construct($subjectInterface)
    {
        $this->subjectInterface = $subjectInterface;
    }

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('nombre')
            ->add('miembros', 'select2', array(
                'class' => $this->subjectInterface,
                'url'   => 'Grupo_autocomplete_miembros',
                'configs' => array(
                    'multiple' => true,//required true or false
                    'width'    => 'off',
                ),
                'attr' => array(
                    'class' => "col-lg-12 col-md-12 col-sm-12 col-xs-12",
                )
            ))
            ->add('creador', 'select2', array(
                'class' => $this->subjectInterface,
                'url'   => 'Grupo_autocomplete_creador',
                'configs' => array(
                    'multiple' => false,//required true or false
                    'width'    => 'off',
                ),
                'attr' => array(
                    'class' => "col-lg-12 col-md-12 col-sm-12 col-xs-12",
                )
            ))
        ;
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'MWSimple\Bundle\ForoBundle\Entity\Grupo'
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'mws_forobundle_grupo';
    }
}


text:
import React from 'react';
import Route from 'react-router-dom/Route';
import Switch from 'react-router-dom/Switch';

import DataPage from './containers/DataPage/DataPage';

export function getRoutesConfig() {
  return [
    {
      name: 'DataPage',
      path: '/',
      Component: DataPage
    }
  ];
}

export function makeRoutes() {
  return (
    <div>
      <Switch>
        {getRoutesConfig().map((route) => (
          <Route {...route}
                 key={route.name}
                 render={() => <route.Component /> }
          />
        ))}
      </Switch>
    </div>
  );
}


text:
import Image from './Image';

export default Image;


text:
"""
https://stackoverflow.com/questions/2776829/difference-between-python-generators-vs-iterators
http://www.diveintopython3.net/iterators.html
https://docs.python.org/2/library/stdtypes.html#string-formatting
"""

list1 = ['a', 'b', 'c', 'd']

"""
Iterating through that list is easily done of course. But say you wanted to go through each item on the list and
then print only 'c' in that list?  And without using a loop? I'm not sure why you'd want to do it - but I guess it couldn't hurt to know :D

Note that the counter is preserved internally and it correctly moves to the next object. 'next' is the ONLY
method that the iterator has.
"""

iterator = iter(list1)
iterator.next()
iterator.next()
print iterator.next()

"""
Writing your own custom iterators is so you can iterate through them and perform whatever operations you want to
on them. Its a good idea to read the stack overflow thread that I refer to at the top - to understand why one
would need to even use custom iterators.

To understand custom iterators though, we first need to understand classes. If you have a simple program, then
you can probably write clean code - just using modules and importing them. Classes are apparently the OOP way
of doing things - I am unclear yet, as to what advantages they offer. So please help :)

All the same, here is a code snippet that shows how to define classes AND custom iterators.
"""

class Test:
    """
    This is how a class is defined along with its methods. The first 3 methods are compulsory
    if you want to create your own iterator. All the fancy filtering logic should go into the next() method.
    """
    def __init__(self, number):
        self.number = number

    def __iter__(self):
        return self

    def next(self):
        fib = self.number
        fib += 2
        self.number = fib
        if fib >= 15:
            raise StopIteration

        return fib

    """
    Since this is a class, you can, in addition to the 3 "iterator" methods, also define additional methods.
    These methods can be invoked by an object as usual.
    """
    def additionalmethod(self):
        print "You can define additional methods here and call that normally"

for i in Test(1):
    """
        This causes the custom next() method of the class to get invoked and jumps 2 steps at a time, instead of 1 by default, had you just
        called next().
        Use format strings instead of concatenating and using str() or repr() to print things.
    """
    print "Value of i is %s" %i

t1 = Test(0)
t1.additionalmethod()


text:
package ecs

import (
	. "aliyun-openapi-go-sdk/core"
	"strconv"
)

type DetachDiskRequest struct {
	RpcRequest
	OwnerId              int
	ResourceOwnerAccount string
	ResourceOwnerId      int
	InstanceId           string
	DiskId               string
	OwnerAccount         string
}

func (r *DetachDiskRequest) SetOwnerId(value int) {
	r.OwnerId = value
	r.QueryParams.Set("OwnerId", strconv.Itoa(value))
}
func (r *DetachDiskRequest) GetOwnerId() int {
	return r.OwnerId
}
func (r *DetachDiskRequest) SetResourceOwnerAccount(value string) {
	r.ResourceOwnerAccount = value
	r.QueryParams.Set("ResourceOwnerAccount", value)
}
func (r *DetachDiskRequest) GetResourceOwnerAccount() string {
	return r.ResourceOwnerAccount
}
func (r *DetachDiskRequest) SetResourceOwnerId(value int) {
	r.ResourceOwnerId = value
	r.QueryParams.Set("ResourceOwnerId", strconv.Itoa(value))
}
func (r *DetachDiskRequest) GetResourceOwnerId() int {
	return r.ResourceOwnerId
}
func (r *DetachDiskRequest) SetInstanceId(value string) {
	r.InstanceId = value
	r.QueryParams.Set("InstanceId", value)
}
func (r *DetachDiskRequest) GetInstanceId() string {
	return r.InstanceId
}
func (r *DetachDiskRequest) SetDiskId(value string) {
	r.DiskId = value
	r.QueryParams.Set("DiskId", value)
}
func (r *DetachDiskRequest) GetDiskId() string {
	return r.DiskId
}
func (r *DetachDiskRequest) SetOwnerAccount(value string) {
	r.OwnerAccount = value
	r.QueryParams.Set("OwnerAccount", value)
}
func (r *DetachDiskRequest) GetOwnerAccount() string {
	return r.OwnerAccount
}

func (r *DetachDiskRequest) Init() {
	r.RpcRequest.Init()
	r.SetVersion(Version)
	r.SetAction("DetachDisk")
	r.SetProduct(Product)
}

type DetachDiskResponse struct {
}

func DetachDisk(req *DetachDiskRequest, accessId, accessSecret string) (*DetachDiskResponse, error) {
	var pResponse DetachDiskResponse
	body, err := ApiHttpRequest(accessId, accessSecret, req)
	if err != nil {
		return nil, err
	}
	ApiUnmarshalResponse(req.GetFormat(), body, &pResponse)
	return &pResponse, err
}


text:
"""
Created on Fri Apr 17 17:23:06 2015

@author: Nick Lewty

Python software for communicating with Hameg power supply

Simple serial communication based on GPIB commands

For more info on commands see data sheet

http://www.hameg.com/manuals.0.html?&no_cache=1&tx_hmdownloads_pi1[mode]=download&tx_hmdownloads_pi1[uid]=7465

"""

import serial

class Hameg(object):
	baudrate = 115200

	def __init__(self, port):
		self.serial = self._open_port(port)

	def _open_port(self, port):
		ser = serial.Serial(port, self.baudrate, timeout=1)
		ser.readline()
		ser.timeout = 1
		return ser

	def _serial_write(self, string):
		self.serial.write(string + '\n')

	def _serial_read(self):
		msg_string = self.serial.readline()
		# Remove any linefeeds etc
		msg_string = msg_string.rstrip()
		return msg_string

	def reset(self):
		self._serial_write('*RST')

	def serial_number(self):
		self._serial_write('*IDN?')
		return self._serial_read()

	def set_voltage(self,channel,value):
		self._serial_write('INST OUT'+str(channel))
		self._serial_write('VOLT ' + str(value))

	def get_voltage(self,channel):
		self._serial_write('INST OUT'+str(channel))
		self._serial_write('MEAS:VOLT?')
		return self._serial_read()

	def set_current(self,channel,value):
		self._serial_write('INST OUT'+str(channel))
		self._serial_write('CURR ' + str(value))

	def get_current(self,channel):
		self._serial_write('INST OUT'+str(channel))
		self._serial_write('MEAS:CURR?')
		return self._serial_read()

	def output_on(self,channel):
		self._serial_write('INST OUT'+str(channel))
		self._serial_write('OUTP ON')

	def output_off(self,channel):
		self._serial_write('INST OUT'+str(channel))
		self._serial_write('OUTP OFF')


text:
package com.g10.ssm.controller.testdatabase;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.g10.ssm.po.testdatabase.ChoiceQuestion;
import com.g10.ssm.po.testdatabase.Exam;
import com.g10.ssm.po.testdatabase.ExamQuestionKey;
import com.g10.ssm.po.testdatabase.Strategy;
import com.g10.ssm.po.testdatabase.Subject;
import com.g10.ssm.po.testdatabase.SubjectCustom;
import com.g10.ssm.po.testdatabase.SubjectQueryVo;
import com.g10.ssm.po.testdatabase.TestItemsDesign;
import com.g10.ssm.service.testdatabase.ChoiceQuestionService;
import com.g10.ssm.service.testdatabase.ExamQuestionService;
import com.g10.ssm.service.testdatabase.ExamService;
import com.g10.ssm.service.testdatabase.StrategyQuestionTypesService;
import com.g10.ssm.service.testdatabase.StrategyService;
import com.g10.ssm.service.testdatabase.SubjectService;
import com.g10.ssm.service.testdatabase.TestItemsDesignService;

@Controller
@RequestMapping("/test")
public class SubjectVoController {
	@Autowired
	private StrategyQuestionTypesService sqts;

	@Autowired
	private TestItemsDesignService tds;

	@Autowired
	private SubjectService subjectService;

	@Autowired
	private ExamQuestionService eqService;

	@Autowired
	private ChoiceQuestionService choiceService;

	@Autowired
	private StrategyService strategyService;

	@Autowired
	private ExamService examService;

	private List<Integer> getAllDids(Integer strategyId) throws Exception{
		if(strategyId != null && strategyId != 0){
			List<Integer> ids = null;
			ids = sqts.selectTidByStrategyId(strategyId);
			return ids;
		}
		return null;
	}

	private TestItemsDesign getTestItemsDesign(Integer id) throws Exception{
		if(id != null && id != 0){
			TestItemsDesign testDesign = null;
			testDesign = tds.queryTestItemsDesignById(id);
			return testDesign;
		}
		return null;
	}

	private List<Subject> getSubjectsById(Integer id) throws Exception{
		if(id != null && id != 0){
			List<Integer> list = null;
			list = eqService.selectSubjectIdByExamId(id);
			if(list != null){
				List<Subject> subjects = new ArrayList<Subject>();
				for(Integer subjectId: list){
					Subject subject = subjectService.querySubjectById(subjectId);
					if(subject != null)
						subjects.add(subject);
				}
				return subjects;
			}
		}
		return null;
	}

	@RequestMapping("/singleChoice")
	@ResponseBody
	public SubjectQueryVo getSingleChoice(Exam exam, String subjectType) throws Exception{
		if(exam != null && exam.getExamId() != null && exam.getStrategyId() != null){
			List<Integer> tids = getAllDids(exam.getStrategyId());
			if(tids != null){
				//获取某种题型下的所有题
				List<SubjectCustom> list = new ArrayList<SubjectCustom>();
				SubjectQueryVo subjectQueryVo = new SubjectQueryVo();
				for(Integer id: tids){
					//获取单道题
					TestItemsDesign testDesign = getTestItemsDesign(id);
					if(testDesign != null && testDesign.getExamType().equals(subjectType)){
						subjectQueryVo.setSingleScore(testDesign.getScore());
						//获取试卷中所有试题
						List<Subject> subjects = getSubjectsById(exam.getExamId());
						for(Subject subject: subjects){
							if(subject.getSubjectType().equals(subjectType)){
								SubjectCustom subjectCustom = new SubjectCustom(subject);
								ChoiceQuestion choice = choiceService.selectChoiceById(subject.getSubjectId());
								subjectCustom.setChoice(choice);
								list.add(subjectCustom);
							}
						}
					}
				}
				subjectQueryVo.setList(list);
				return subjectQueryVo;
			}
		}
		return null;
	}

	private boolean createExam(Integer strategyId, Integer examId) throws Exception{
		if(strategyId != null && strategyId != 0){
			if(examId != null && examId != 0){
				List<Integer> ids = null;
				ids = sqts.selectTidByStrategyId(strategyId);
				if(ids != null){
					for(Integer id: ids){
						TestItemsDesign testDesign = getTestItemsDesign(id);
						SubjectCustom subject = new SubjectCustom();
						subject.setLowerlimitDifficultyId(testDesign.getLowerlimitDifficultyId());
						subject.setToplimitDifficultyId(testDesign.getToplimitDifficultyId());
						subject.setSubjectNum(testDesign.getNumber());
						subject.setSubjectType(testDesign.getExamType());
						List<Integer> sids = subjectService.selectIdsByExample(subject);
						if(sids.size() < subject.getSubjectNum())
							return false;
						for(Integer sid: sids){
							ExamQuestionKey examQuestion = new ExamQuestionKey();
							examQuestion.setExamId(examId);
							examQuestion.setSubjectId(sid);
							int result = eqService.saveExamQuestion(examQuestion);
							if(result == 0) return false;
						}
					}
				}
			}
			return true;
		}
		return false;
	}

	@RequestMapping("/submit/exam")
	public Integer generateExam(Integer strategyId, String examName) throws Exception{
		if(examName != null && strategyId != null && strategyId != 0){
			Exam exam = new Exam();
			exam.setName(examName);
			exam.setStrategyId(strategyId);
			int result = examService.saveExam(exam);
			Exam exam0 = examService.queryExamByExam(exam);
			boolean ok = createExam(exam0.getStrategyId(), exam0.getExamId());
			return ok ? result : 0;
		}
		return 0;
	}

	@RequestMapping("/testpaper")
	public String getTest(Model model, Integer examId, Integer strategyId) throws Exception{
		model.addAttribute("examId", examId);
		model.addAttribute("strategyId", strategyId);
		return "questionBank/test";
	}

	@RequestMapping("/strategy/all")
	@ResponseBody
	public List<Strategy> getAllStrategy() throws Exception{
		List<Strategy> list = null;
		list = strategyService.queryStrategy();
		return list;
	}

	@RequestMapping("/add/exam")
	public String intoExamAdd(){
		return "Strategy/ExaminationAdd";
	}

}


text:
var ng = {
	reference : {
		id : ''
	},
	formProcess : function(Obj, act, redirect, callback, callbackoption, isCloseModal) {
		this.stopSubmitOnPressEnter(Obj);
		//callback handler for form submit
		switch (act) {
		case 'delete':
			msg = {
				success : 'Data Berhasil Dihapus!',
				error : 'Data Gagal Dihapus!'
			};
			break;
        case 'reset_password':
            msg = {
                success : 'Password baru berhasil dikirim !',
                error : 'Data Gagal Dihapus!'
            };
                break;
		default:
			msg = {
				success : 'Data Berhasil Disimpan!',
				error : 'Data Gagal Disimpan!'
			};
		}
		$(Obj).submit(function(e) {
			var formObj = $(this);
			var formURL = formObj.attr("action");
			var formData = new FormData(this);
            if (isCloseModal == false) {
            } else {
                CloseModalBox();
            }
            $('#loader_area').show();
            $('button').attr('disabled','disabled');
			$.ajax({
				url : formURL,
				type : 'POST',
				data : formData,
				mimeType : "multipart/form-data",
				contentType : false,
				cache : false,
				processData : false,
				success : function(data, textStatus, jqXHR) {
                    $('button').removeAttr('disabled');
                    $('#loader_area').hide();

					if (data == 0) {
						alertify.error(msg.error);
					} else {
						alertify.success(msg.success);
					}
					if (typeof callback === "function") {
						callback(callbackoption);
					}
					if (redirect) {
						var url = redirect;
						window.location.hash = url;
						ng.LoadAjaxContent(url);
						return false;
					}
					// alert(data);
					ng.reference.id = data;
				},
				error : function(jqXHR, textStatus, errorThrown) {
                    $('button').removeAttr('disabled');
                    $('#loader_area').hide();
					alertify.error(msg.error + "\n" + jqXHR.statusText);
				}
			});
			e.preventDefault(); //Prevent Default action.
			// e.unbind();
		});
		if (act == 'insert') { // Ctrl + s
			$(document).on('keydown', function(e) {
				if (e.ctrlKey && e.which === 83) {
					e.preventDefault();
					$(Obj).submit();
					return false;
				}
			});
		} else if (act == 'update') {
			$(document).on('keydown', function(e) {
				if (e.ctrlKey && e.which === 83) {
					e.preventDefault();
					$(Obj).submit();
					return false;
				}
			});
		}
	},
	LoadAjaxContentPost : function(url, form, target, callback, callbackoption) {
		$('#loader_area').show();
		$.post(url, form.serialize(), function(html) {
            $('#loader_area').hide();
			if (target) {
				$(target).html(html);
			} else {
				$('#test').html(html);
			}
			// $('.preloader').hide();
			if (typeof callback === "function") {
				callback(callbackoption);
			}
			$('.breadcrumb a').click(function(e) {
				e.preventDefault(); //Prevent Default action.
				// e.unbind();
				url = $(this).attr('href');
				window.location.hash = url;
				ng.LoadAjaxContent(url);
				return false;
			});
			return false;
		});
	},
	LoadAjaxContent : function(url, target) {
		// $('.preloader').show();
		// url = $(this).attr('href');
		// window.location.hash = location;
        $('#loader_area').show();
		$.ajax({
			mimeType : 'text/html; charset=utf-8', // ! Need set mimeType only when run from local file
			url : url,
			type : 'GET',
			success : function(html) {
                $('#loader_area').hide();
				if (target) {
					$(target).html(html);
				} else {
					$('#test').html(html);
				}
				// $('.preloader').hide();
				$('.breadcrumb a').click(function(e) {
					e.preventDefault(); //Prevent Default action.
					url = $(this).attr('href');
					// window.location.hash = location;
					ng.LoadAjaxContent(url);
					// e.unbind();
					return false;
				});
			},
			error : function(jqXHR, textStatus, errorThrown) {
				alertify.alert(textStatus, errorThrown);
				$('#loader_area').hide();
			},
			dataType : "html",
			async : false
		});
	},
	stopSubmitOnPressEnter : function(Obj) {
		$(Obj).find(":input").keypress(function(e) {
			var code = e.keyCode || e.which;
			var src = e.srcElement || e.target;
			if (src.tagName.toLowerCase() != "textarea") {
				if (code == 13) {
					if (e.preventDefault) {
						e.preventDefault();
					} else {
						e.returnValue = false;
					}
					e.preventDefault();
					return false;
				}
			}
		});
	},
	LoadAjaxTabContent : function(opt) {
		$(opt.block).block({
			message : ''
		});
		$.get(opt.url, function(html) {
			$(opt.container).html(html);
			$(opt.block).unblock();
		});
	},
	exportTo : function(mode, action, title) { // author gunaones
		$('#ajaxFormCari').after(
				'<form method="post" action="' + action
						+ '" id="ajaxFormPrint"></form>');
		$("#ajaxFormCari").children().clone().appendTo('#ajaxFormPrint');
		if (mode == 'pdf') {
			html = '';
			OpenModalBox(title, html, '', 'large');
			$('#ajaxFormPrint').attr('target', 'iframeCetak');
		} else if (mode == 'excel') {
			$('#ajaxFormPrint').removeAttr('target');
		} else if (mode == 'word') {
			$('#ajaxFormPrint').removeAttr('target');
		}
		$('#ajaxFormPrint').submit();
		$('#ajaxFormPrint').remove();
	},
	postOpenModalBox : function(url, title, footer, size){
        $.post(url, function (html) {
            OpenModalBox(title, html, footer, size);
        });
    },
    setRequired : function(objRequired){
        $.each(objRequired, function(index, val) {
             if(val[1]){
                $(val[0]).prop('required', true);
             }else{
                $(val[0]).prop('required', false);
             }
        });
    }
}


text:
<?xml version="1.0" encoding="utf-8"?>
<reflection>
  <assemblies>
    <assembly name="System.Data.Entity">
      <assemblydata version="4.0.0.0" culture="" key="00000000000000000400000000000000" hash="SHA1" />
      <attributes>
        <attribute>
          <type api="T:System.Runtime.CompilerServices.ExtensionAttribute" ref="true" />
        </attribute>
        <attribute>
          <type api="T:System.Security.SecurityCriticalAttribute" ref="true" />
        </attribute>
        <attribute>
          <type api="T:System.Runtime.InteropServices.ComVisibleAttribute" ref="true" />
          <argument>
            <type api="T:System.Boolean" ref="false" />
            <value>False</value>
          </argument>
        </attribute>
        <attribute>
          <type api="T:System.CLSCompliantAttribute" ref="true" />
          <argument>
            <type api="T:System.Boolean" ref="false" />
            <value>True</value>
          </argument>
        </attribute>
        <attribute>
          <type api="T:System.Security.AllowPartiallyTrustedCallersAttribute" ref="true" />
        </attribute>
        <attribute>
          <type api="T:System.Reflection.AssemblyTitleAttribute" ref="true" />
          <argument>
            <type api="T:System.String" ref="true" />
            <value>System.Data.Entity.dll</value>
          </argument>
        </attribute>
        <attribute>
          <type api="T:System.Reflection.AssemblyDescriptionAttribute" ref="true" />
          <argument>
            <type api="T:System.String" ref="true" />
            <value>System.Data.Entity.dll</value>
          </argument>
        </attribute>
        <attribute>
          <type api="T:System.Reflection.AssemblyDefaultAliasAttribute" ref="true" />
          <argument>
            <type api="T:System.String" ref="true" />
            <value>System.Data.Entity.dll</value>
          </argument>
        </attribute>
        <attribute>
          <type api="T:System.Reflection.AssemblyCompanyAttribute" ref="true" />
          <argument>
            <type api="T:System.String" ref="true" />
            <value>Microsoft Corporation</value>
          </argument>
        </attribute>
        <attribute>
          <type api="T:System.Reflection.AssemblyProductAttribute" ref="true" />
          <argument>
            <type api="T:System.String" ref="true" />
            <value>Microsoft® .NET Framework</value>
          </argument>
        </attribute>
        <attribute>
          <type api="T:System.Reflection.AssemblyCopyrightAttribute" ref="true" />
          <argument>
            <type api="T:System.String" ref="true" />
            <value>© Microsoft Corporation.  All rights reserved.</value>
          </argument>
        </attribute>
        <attribute>
          <type api="T:System.Reflection.AssemblyFileVersionAttribute" ref="true" />
          <argument>
            <type api="T:System.String" ref="true" />
            <value>4.6.81.0</value>
          </argument>
        </attribute>
        <attribute>
          <type api="T:System.Reflection.AssemblyInformationalVersionAttribute" ref="true" />
          <argument>
            <type api="T:System.String" ref="true" />
            <value>4.6.81.0</value>
          </argument>
        </attribute>
        <attribute>
          <type api="T:System.Resources.SatelliteContractVersionAttribute" ref="true" />
          <argument>
            <type api="T:System.String" ref="true" />
            <value>4.0.0.0</value>
          </argument>
        </attribute>
        <attribute>
          <type api="T:System.Resources.NeutralResourcesLanguageAttribute" ref="true" />
          <argument>
            <type api="T:System.String" ref="true" />
            <value>en-US</value>
          </argument>
        </attribute>
        <attribute>
          <type api="T:System.Reflection.AssemblyDelaySignAttribute" ref="true" />
          <argument>
            <type api="T:System.Boolean" ref="false" />
            <value>True</value>
          </argument>
        </attribute>
        <attribute>
          <type api="T:System.Reflection.AssemblyKeyFileAttribute" ref="true" />
          <argument>
            <type api="T:System.String" ref="true" />
            <value>f:\dd\tools\devdiv\EcmaPublicKey.snk</value>
          </argument>
        </attribute>
        <attribute>
          <type api="T:System.Reflection.AssemblySignatureKeyAttribute" ref="true" />
          <argument>
            <type api="T:System.String" ref="true" />
            <value>002400000c800000140100000602000000240000525341310008000001000100613399aff18ef1a2c2514a273a42d9042b72321f1757102df9ebada69923e2738406c21e5b801552ab8d200a65a235e001ac9adc25f2d811eb09496a4c6a59d4619589c69f5baf0c4179a47311d92555cd006acc8b5959f2bd6e10e360c34537a1d266da8085856583c85d81da7f3ec01ed9564c58d93d713cd0172c8e23a10f0239b80c96b07736f5d8b022542a4e74251a5f432824318b3539a5a087f8e53d2f135f9ca47f3bb2e10aff0af0849504fb7cea3ff192dc8de0edad64c68efde34c56d302ad55fd6e80f302d5efcdeae953658d3452561b5f36c542efdbdd9f888538d374cef106acf7d93a4445c3c73cd911f0571aaf3d54da12b11ddec375b3</value>
          </argument>
          <argument>
            <type api="T:System.String" ref="true" />
            <value>a5a866e1ee186f807668209f3b11236ace5e21f117803a3143abb126dd035d7d2f876b6938aaf2ee3414d5420d753621400db44a49c486ce134300a2106adb6bdb433590fef8ad5c43cba82290dc49530effd86523d9483c00f458af46890036b0e2c61d077d7fbac467a506eba29e467a87198b053c749aa2a4d2840c784e6d</value>
          </argument>
        </attribute>
      </attributes>
    </assembly>
  </assemblies>
  <apis>
    <api id="N:System.Data.Common.EntitySql">
      <topicdata group="api" />
      <apidata name="System.Data.Common.EntitySql" group="namespace" />
      <elements>
        <element api="T:System.Data.Common.EntitySql.ParseResult" />
        <element api="T:System.Data.Common.EntitySql.FunctionDefinition" />
        <element api="T:System.Data.Common.EntitySql.EntitySqlParser" />
      </elements>
      <file name="c921729f-8ee4-316b-6cbd-e5efd3687594" />
    </api>
    <api id="T:System.Data.Common.EntitySql.EntitySqlParser">
      <topicdata group="api" allMembersTopicId="AllMembers.T:System.Data.Common.EntitySql.EntitySqlParser" />
      <apidata name="EntitySqlParser" group="type" subgroup="class" />
      <typedata visibility="public" sealed="true" serializable="false" />
      <family>
        <ancestors>
          <type api="T:System.Object" ref="true" />
        </ancestors>
      </family>
      <containers>
        <library assembly="System.Data.Entity" module="System.Data.Entity" kind="DynamicallyLinkedLibrary">
          <assemblydata version="4.6.81.0" />
        </library>
        <namespace api="N:System.Data.Common.EntitySql" />
      </containers>
      <file name="ec07e642-4c84-6a56-c1ff-3bbf2b3101ff" />
    </api>
    <api id="AllMembers.T:System.Data.Common.EntitySql.EntitySqlParser">
      <topicdata name="EntitySqlParser" group="list" subgroup="members" typeTopicId="T:System.Data.Common.EntitySql.EntitySqlParser" />
      <apidata name="EntitySqlParser" group="type" subgroup="class" />
      <typedata visibility="public" sealed="true" serializable="false" />
      <elements>
        <element api="M:System.Object.Equals(System.Object)" />
        <element api="M:System.Object.GetHashCode" />
        <element api="M:System.Object.GetType" />
        <element api="M:System.Object.ToString" />
        <element api="M:System.Data.Common.EntitySql.EntitySqlParser.Parse(System.String,System.Data.Common.CommandTrees.DbParameterReferenceExpression[])" />
        <element api="M:System.Data.Common.EntitySql.EntitySqlParser.ParseLambda(System.String,System.Data.Common.CommandTrees.DbVariableReferenceExpression[])" />
      </elements>
      <containers>
        <library assembly="System.Data.Entity" module="System.Data.Entity" kind="DynamicallyLinkedLibrary">
          <assemblydata version="4.6.81.0" />
        </library>
        <namespace api="N:System.Data.Common.EntitySql" />
        <type api="T:System.Data.Common.EntitySql.EntitySqlParser" />
      </containers>
      <file name="611eeae5-129c-0ef5-ee45-5b39f5887137" />
    </api>
    <api id="Methods.T:System.Data.Common.EntitySql.EntitySqlParser">
      <topicdata name="EntitySqlParser" group="list" subgroup="Methods" typeTopicId="T:System.Data.Common.EntitySql.EntitySqlParser" />
      <apidata name="EntitySqlParser" group="type" subgroup="class" />
      <typedata visibility="public" sealed="true" serializable="false" />
      <elements>
        <element api="M:System.Object.Equals(System.Object)" />
        <element api="M:System.Object.GetHashCode" />
        <element api="M:System.Object.GetType" />
        <element api="M:System.Object.ToString" />
        <element api="M:System.Data.Common.EntitySql.EntitySqlParser.Parse(System.String,System.Data.Common.CommandTrees.DbParameterReferenceExpression[])" />
        <element api="M:System.Data.Common.EntitySql.EntitySqlParser.ParseLambda(System.String,System.Data.Common.CommandTrees.DbVariableReferenceExpression[])" />
      </elements>
      <containers>
        <library assembly="System.Data.Entity" module="System.Data.Entity" kind="DynamicallyLinkedLibrary">
          <assemblydata version="4.6.81.0" />
        </library>
        <namespace api="N:System.Data.Common.EntitySql" />
        <type api="T:System.Data.Common.EntitySql.EntitySqlParser" />
      </containers>
      <file name="6cbc0713-ce8f-920a-c59f-0fc2e049728e" />
    </api>
    <api id="M:System.Data.Common.EntitySql.EntitySqlParser.Parse(System.String,System.Data.Common.CommandTrees.DbParameterReferenceExpression[])">
      <topicdata group="api" />
      <apidata name="Parse" group="member" subgroup="method" />
      <memberdata visibility="public" />
      <proceduredata virtual="false" />
      <parameters>
        <parameter name="query">
          <type api="T:System.String" ref="true" />
        </parameter>
        <parameter name="parameters" params="true">
          <arrayOf rank="1">
            <type api="T:System.Data.Common.CommandTrees.DbParameterReferenceExpression" ref="true" />
          </arrayOf>
        </parameter>
      </parameters>
      <returns>
        <type api="T:System.Data.Common.EntitySql.ParseResult" ref="true" />
      </returns>
      <containers>
        <library assembly="System.Data.Entity" module="System.Data.Entity" kind="DynamicallyLinkedLibrary">
          <assemblydata version="4.6.81.0" />
        </library>
        <namespace api="N:System.Data.Common.EntitySql" />
        <type api="T:System.Data.Common.EntitySql.EntitySqlParser" ref="true" />
      </containers>
      <file name="dd7d7d68-c407-3a01-4c03-06594a512662" />
    </api>
    <api id="M:System.Data.Common.EntitySql.EntitySqlParser.ParseLambda(System.String,System.Data.Common.CommandTrees.DbVariableReferenceExpression[])">
      <topicdata group="api" />
      <apidata name="ParseLambda" group="member" subgroup="method" />
      <memberdata visibility="public" />
      <proceduredata virtual="false" />
      <parameters>
        <parameter name="query">
          <type api="T:System.String" ref="true" />
        </parameter>
        <parameter name="variables" params="true">
          <arrayOf rank="1">
            <type api="T:System.Data.Common.CommandTrees.DbVariableReferenceExpression" ref="true" />
          </arrayOf>
        </parameter>
      </parameters>
      <returns>
        <type api="T:System.Data.Common.CommandTrees.DbLambda" ref="true" />
      </returns>
      <containers>
        <library assembly="System.Data.Entity" module="System.Data.Entity" kind="DynamicallyLinkedLibrary">
          <assemblydata version="4.6.81.0" />
        </library>
        <namespace api="N:System.Data.Common.EntitySql" />
        <type api="T:System.Data.Common.EntitySql.EntitySqlParser" ref="true" />
      </containers>
      <file name="0fb6b90e-bed4-cf31-cb3e-8ee82094b9da" />
    </api>
    <api id="T:System.Data.Common.EntitySql.FunctionDefinition">
      <topicdata group="api" allMembersTopicId="AllMembers.T:System.Data.Common.EntitySql.FunctionDefinition" />
      <apidata name="FunctionDefinition" group="type" subgroup="class" />
      <typedata visibility="public" sealed="true" serializable="false" />
      <family>
        <ancestors>
          <type api="T:System.Object" ref="true" />
        </ancestors>
      </family>
      <containers>
        <library assembly="System.Data.Entity" module="System.Data.Entity" kind="DynamicallyLinkedLibrary">
          <assemblydata version="4.6.81.0" />
        </library>
        <namespace api="N:System.Data.Common.EntitySql" />
      </containers>
      <file name="31aae0fb-1b5e-ef83-cba7-edecbb260d3e" />
    </api>
    <api id="AllMembers.T:System.Data.Common.EntitySql.FunctionDefinition">
      <topicdata name="FunctionDefinition" group="list" subgroup="members" typeTopicId="T:System.Data.Common.EntitySql.FunctionDefinition" />
      <apidata name="FunctionDefinition" group="type" subgroup="class" />
      <typedata visibility="public" sealed="true" serializable="false" />
      <elements>
        <element api="M:System.Object.Equals(System.Object)" />
        <element api="M:System.Object.GetHashCode" />
        <element api="M:System.Object.GetType" />
        <element api="M:System.Object.ToString" />
        <element api="P:System.Data.Common.EntitySql.FunctionDefinition.EndPosition" />
        <element api="P:System.Data.Common.EntitySql.FunctionDefinition.Lambda" />
        <element api="P:System.Data.Common.EntitySql.FunctionDefinition.Name" />
        <element api="P:System.Data.Common.EntitySql.FunctionDefinition.StartPosition" />
      </elements>
      <containers>
        <library assembly="System.Data.Entity" module="System.Data.Entity" kind="DynamicallyLinkedLibrary">
          <assemblydata version="4.6.81.0" />
        </library>
        <namespace api="N:System.Data.Common.EntitySql" />
        <type api="T:System.Data.Common.EntitySql.FunctionDefinition" />
      </containers>
      <file name="204f7de5-4cac-5242-4f82-c1daaeee3508" />
    </api>
    <api id="Methods.T:System.Data.Common.EntitySql.FunctionDefinition">
      <topicdata name="FunctionDefinition" group="list" subgroup="Methods" typeTopicId="T:System.Data.Common.EntitySql.FunctionDefinition" />
      <apidata name="FunctionDefinition" group="type" subgroup="class" />
      <typedata visibility="public" sealed="true" serializable="false" />
      <elements>
        <element api="M:System.Object.Equals(System.Object)" />
        <element api="M:System.Object.GetHashCode" />
        <element api="M:System.Object.GetType" />
        <element api="M:System.Object.ToString" />
      </elements>
      <containers>
        <library assembly="System.Data.Entity" module="System.Data.Entity" kind="DynamicallyLinkedLibrary">
          <assemblydata version="4.6.81.0" />
        </library>
        <namespace api="N:System.Data.Common.EntitySql" />
        <type api="T:System.Data.Common.EntitySql.FunctionDefinition" />
      </containers>
      <file name="45ac8506-8d4e-3e50-f0d6-729cf27eb184" />
    </api>
    <api id="Properties.T:System.Data.Common.EntitySql.FunctionDefinition">
      <topicdata name="FunctionDefinition" group="list" subgroup="Properties" typeTopicId="T:System.Data.Common.EntitySql.FunctionDefinition" />
      <apidata name="FunctionDefinition" group="type" subgroup="class" />
      <typedata visibility="public" sealed="true" serializable="false" />
      <elements>
        <element api="P:System.Data.Common.EntitySql.FunctionDefinition.EndPosition" />
        <element api="P:System.Data.Common.EntitySql.FunctionDefinition.Lambda" />
        <element api="P:System.Data.Common.EntitySql.FunctionDefinition.Name" />
        <element api="P:System.Data.Common.EntitySql.FunctionDefinition.StartPosition" />
      </elements>
      <containers>
        <library assembly="System.Data.Entity" module="System.Data.Entity" kind="DynamicallyLinkedLibrary">
          <assemblydata version="4.6.81.0" />
        </library>
        <namespace api="N:System.Data.Common.EntitySql" />
        <type api="T:System.Data.Common.EntitySql.FunctionDefinition" />
      </containers>
      <file name="bc49f513-0971-0206-a908-6aa362b77791" />
    </api>
    <api id="P:System.Data.Common.EntitySql.FunctionDefinition.EndPosition">
      <topicdata group="api" />
      <apidata name="EndPosition" group="member" subgroup="property" />
      <memberdata visibility="public" />
      <proceduredata virtual="false" />
      <propertydata get="true" />
      <getter name="get_EndPosition" />
      <returns>
        <type api="T:System.Int32" ref="false" />
      </returns>
      <containers>
        <library assembly="System.Data.Entity" module="System.Data.Entity" kind="DynamicallyLinkedLibrary">
          <assemblydata version="4.6.81.0" />
        </library>
        <namespace api="N:System.Data.Common.EntitySql" />
        <type api="T:System.Data.Common.EntitySql.FunctionDefinition" ref="true" />
      </containers>
      <file name="a5d68c3d-e57a-dfc0-c33d-78a451281bc4" />
    </api>
    <api id="P:System.Data.Common.EntitySql.FunctionDefinition.Lambda">
      <topicdata group="api" />
      <apidata name="Lambda" group="member" subgroup="property" />
      <memberdata visibility="public" />
      <proceduredata virtual="false" />
      <propertydata get="true" />
      <getter name="get_Lambda" />
      <returns>
        <type api="T:System.Data.Common.CommandTrees.DbLambda" ref="true" />
      </returns>
      <containers>
        <library assembly="System.Data.Entity" module="System.Data.Entity" kind="DynamicallyLinkedLibrary">
          <assemblydata version="4.6.81.0" />
        </library>
        <namespace api="N:System.Data.Common.EntitySql" />
        <type api="T:System.Data.Common.EntitySql.FunctionDefinition" ref="true" />
      </containers>
      <file name="f65c2efa-a151-3120-2620-0a938054fc17" />
    </api>
    <api id="P:System.Data.Common.EntitySql.FunctionDefinition.Name">
      <topicdata group="api" />
      <apidata name="Name" group="member" subgroup="property" />
      <memberdata visibility="public" />
      <proceduredata virtual="false" />
      <propertydata get="true" />
      <getter name="get_Name" />
      <returns>
        <type api="T:System.String" ref="true" />
      </returns>
      <containers>
        <library assembly="System.Data.Entity" module="System.Data.Entity" kind="DynamicallyLinkedLibrary">
          <assemblydata version="4.6.81.0" />
        </library>
        <namespace api="N:System.Data.Common.EntitySql" />
        <type api="T:System.Data.Common.EntitySql.FunctionDefinition" ref="true" />
      </containers>
      <file name="5b889531-4f89-a5c9-44bf-acbaeb9f9329" />
    </api>
    <api id="P:System.Data.Common.EntitySql.FunctionDefinition.StartPosition">
      <topicdata group="api" />
      <apidata name="StartPosition" group="member" subgroup="property" />
      <memberdata visibility="public" />
      <proceduredata virtual="false" />
      <propertydata get="true" />
      <getter name="get_StartPosition" />
      <returns>
        <type api="T:System.Int32" ref="false" />
      </returns>
      <containers>
        <library assembly="System.Data.Entity" module="System.Data.Entity" kind="DynamicallyLinkedLibrary">
          <assemblydata version="4.6.81.0" />
        </library>
        <namespace api="N:System.Data.Common.EntitySql" />
        <type api="T:System.Data.Common.EntitySql.FunctionDefinition" ref="true" />
      </containers>
      <file name="75c4fe9b-da2a-5a53-5a32-1edcf8b1e3e1" />
    </api>
    <api id="T:System.Data.Common.EntitySql.ParseResult">
      <topicdata group="api" allMembersTopicId="AllMembers.T:System.Data.Common.EntitySql.ParseResult" />
      <apidata name="ParseResult" group="type" subgroup="class" />
      <typedata visibility="public" sealed="true" serializable="false" />
      <family>
        <ancestors>
          <type api="T:System.Object" ref="true" />
        </ancestors>
      </family>
      <containers>
        <library assembly="System.Data.Entity" module="System.Data.Entity" kind="DynamicallyLinkedLibrary">
          <assemblydata version="4.6.81.0" />
        </library>
        <namespace api="N:System.Data.Common.EntitySql" />
      </containers>
      <file name="a9bd1cb6-d892-62d4-e09b-4f2f4dc7acd6" />
    </api>
    <api id="AllMembers.T:System.Data.Common.EntitySql.ParseResult">
      <topicdata name="ParseResult" group="list" subgroup="members" typeTopicId="T:System.Data.Common.EntitySql.ParseResult" />
      <apidata name="ParseResult" group="type" subgroup="class" />
      <typedata visibility="public" sealed="true" serializable="false" />
      <elements>
        <element api="M:System.Object.Equals(System.Object)" />
        <element api="M:System.Object.GetHashCode" />
        <element api="M:System.Object.GetType" />
        <element api="M:System.Object.ToString" />
        <element api="P:System.Data.Common.EntitySql.ParseResult.CommandTree" />
        <element api="P:System.Data.Common.EntitySql.ParseResult.FunctionDefinitions" />
      </elements>
      <containers>
        <library assembly="System.Data.Entity" module="System.Data.Entity" kind="DynamicallyLinkedLibrary">
          <assemblydata version="4.6.81.0" />
        </library>
        <namespace api="N:System.Data.Common.EntitySql" />
        <type api="T:System.Data.Common.EntitySql.ParseResult" />
      </containers>
      <file name="4b2f7d4f-0bd4-734e-365e-53ba1c14c750" />
    </api>
    <api id="Methods.T:System.Data.Common.EntitySql.ParseResult">
      <topicdata name="ParseResult" group="list" subgroup="Methods" typeTopicId="T:System.Data.Common.EntitySql.ParseResult" />
      <apidata name="ParseResult" group="type" subgroup="class" />
      <typedata visibility="public" sealed="true" serializable="false" />
      <elements>
        <element api="M:System.Object.Equals(System.Object)" />
        <element api="M:System.Object.GetHashCode" />
        <element api="M:System.Object.GetType" />
        <element api="M:System.Object.ToString" />
      </elements>
      <containers>
        <library assembly="System.Data.Entity" module="System.Data.Entity" kind="DynamicallyLinkedLibrary">
          <assemblydata version="4.6.81.0" />
        </library>
        <namespace api="N:System.Data.Common.EntitySql" />
        <type api="T:System.Data.Common.EntitySql.ParseResult" />
      </containers>
      <file name="ba84316f-0954-9249-9236-6de86fc5c4d5" />
    </api>
    <api id="Properties.T:System.Data.Common.EntitySql.ParseResult">
      <topicdata name="ParseResult" group="list" subgroup="Properties" typeTopicId="T:System.Data.Common.EntitySql.ParseResult" />
      <apidata name="ParseResult" group="type" subgroup="class" />
      <typedata visibility="public" sealed="true" serializable="false" />
      <elements>
        <element api="P:System.Data.Common.EntitySql.ParseResult.CommandTree" />
        <element api="P:System.Data.Common.EntitySql.ParseResult.FunctionDefinitions" />
      </elements>
      <containers>
        <library assembly="System.Data.Entity" module="System.Data.Entity" kind="DynamicallyLinkedLibrary">
          <assemblydata version="4.6.81.0" />
        </library>
        <namespace api="N:System.Data.Common.EntitySql" />
        <type api="T:System.Data.Common.EntitySql.ParseResult" />
      </containers>
      <file name="165e9436-19af-91fa-20b6-682312260d4d" />
    </api>
    <api id="P:System.Data.Common.EntitySql.ParseResult.CommandTree">
      <topicdata group="api" />
      <apidata name="CommandTree" group="member" subgroup="property" />
      <memberdata visibility="public" />
      <proceduredata virtual="false" />
      <propertydata get="true" />
      <getter name="get_CommandTree" />
      <returns>
        <type api="T:System.Data.Common.CommandTrees.DbCommandTree" ref="true" />
      </returns>
      <containers>
        <library assembly="System.Data.Entity" module="System.Data.Entity" kind="DynamicallyLinkedLibrary">
          <assemblydata version="4.6.81.0" />
        </library>
        <namespace api="N:System.Data.Common.EntitySql" />
        <type api="T:System.Data.Common.EntitySql.ParseResult" ref="true" />
      </containers>
      <file name="1c370617-a0a0-f641-ac1a-2e8f66630766" />
    </api>
    <api id="P:System.Data.Common.EntitySql.ParseResult.FunctionDefinitions">
      <topicdata group="api" />
      <apidata name="FunctionDefinitions" group="member" subgroup="property" />
      <memberdata visibility="public" />
      <proceduredata virtual="false" />
      <propertydata get="true" />
      <getter name="get_FunctionDefinitions" />
      <returns>
        <type api="T:System.Collections.ObjectModel.ReadOnlyCollection`1" ref="true">
          <specialization>
            <type api="T:System.Data.Common.EntitySql.FunctionDefinition" ref="true" />
          </specialization>
        </type>
      </returns>
      <containers>
        <library assembly="System.Data.Entity" module="System.Data.Entity" kind="DynamicallyLinkedLibrary">
          <assemblydata version="4.6.81.0" />
        </library>
        <namespace api="N:System.Data.Common.EntitySql" />
        <type api="T:System.Data.Common.EntitySql.ParseResult" ref="true" />
      </containers>
      <file name="e6499fde-c0df-61bd-a8ac-4fbaca790fb0" />
    </api>
  </apis>
</reflection>


text:
class PrefService;

namespace base {
class FilePath;
class SequencedTaskRunner;
}

namespace favicon_base {
struct FaviconImageResult;
}

namespace query_parser {
enum class MatchingAlgorithm;
}

namespace bookmarks {

class BookmarkCodecTest;
class BookmarkExpandedStateTracker;
class BookmarkLoadDetails;
class BookmarkModelObserver;
class BookmarkStorage;
class BookmarkUndoDelegate;
class ModelLoader;
class ScopedGroupBookmarkActions;
class TestBookmarkClient;
class TitledUrlIndex;
class UrlIndex;

struct UrlAndTitle;
struct TitledUrlMatch;

// BookmarkModel --------------------------------------------------------------

// BookmarkModel provides a directed acyclic graph of URLs and folders.
// Three graphs are provided for the three entry points: those on the 'bookmarks
// bar', those in the 'other bookmarks' folder and those in the 'mobile' folder.
//
// An observer may be attached to observe relevant events.
//
// You should NOT directly create a BookmarkModel, instead go through the
// BookmarkModelFactory.
class BookmarkModel : public BookmarkUndoProvider,
                      public KeyedService {
 public:
  explicit BookmarkModel(std::unique_ptr<BookmarkClient> client);
  ~BookmarkModel() override;

  // Loads the bookmarks. This is called upon creation of the BookmarkModel. You
  // need not invoke this directly. All load operations will be executed on
  // |io_task_runner|. |ui_task_runner| is the task runner the model runs on.
  void Load(PrefService* pref_service,
            const base::FilePath& profile_path,
            const scoped_refptr<base::SequencedTaskRunner>& io_task_runner,
            const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner);

  // Returns true if the model finished loading.
  bool loaded() const {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    return loaded_;
  }

  // Returns the object responsible for tracking loading.
  scoped_refptr<ModelLoader> model_loader();

  // Returns the root node. The 'bookmark bar' node and 'other' node are
  // children of the root node.
  const BookmarkNode* root_node() const {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    return root_;
  }

  // Returns the 'bookmark bar' node. This is NULL until loaded.
  const BookmarkNode* bookmark_bar_node() const {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    return bookmark_bar_node_;
  }

  // Returns the 'other' node. This is NULL until loaded.
  const BookmarkNode* other_node() const {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    return other_node_;
  }

  // Returns the 'mobile' node. This is NULL until loaded.
  const BookmarkNode* mobile_node() const {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    return mobile_node_;
  }

  bool is_root_node(const BookmarkNode* node) const {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    return node == root_;
  }

  // Returns whether the given |node| is one of the permanent nodes - root node,
  // 'bookmark bar' node, 'other' node or 'mobile' node, or one of the root
  // nodes supplied by the |client_|.
  bool is_permanent_node(const BookmarkNode* node) const {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    return node && (node == root_ || node->parent() == root_);
  }

  void AddObserver(BookmarkModelObserver* observer);
  void RemoveObserver(BookmarkModelObserver* observer);

  // Notifies the observers that an extensive set of changes is about to happen,
  // such as during import or sync, so they can delay any expensive UI updates
  // until it's finished.
  void BeginExtensiveChanges();
  void EndExtensiveChanges();

  // Returns true if this bookmark model is currently in a mode where extensive
  // changes might happen, such as for import and sync. This is helpful for
  // observers that are created after the mode has started, and want to check
  // state during their own initializer, such as the NTP.
  bool IsDoingExtensiveChanges() const { return extensive_changes_ > 0; }

  // Removes |node| from the model and deletes it. Removing a folder node
  // recursively removes all nodes. Observers are notified immediately. |node|
  // must not be a permanent node.
  void Remove(const BookmarkNode* node);

  // Removes all the non-permanent bookmark nodes that are editable by the user.
  // Observers are only notified when all nodes have been removed. There is no
  // notification for individual node removals.
  void RemoveAllUserBookmarks();

  // Moves |node| to |new_parent| and inserts it at the given |index|.
  void Move(const BookmarkNode* node,
            const BookmarkNode* new_parent,
            size_t index);

  // Inserts a copy of |node| into |new_parent| at |index|.
  void Copy(const BookmarkNode* node,
            const BookmarkNode* new_parent,
            size_t index);

  // Returns the favicon for |node|. If the favicon has not yet been loaded,
  // a load will be triggered and the observer of the model notified when done.
  // This also means that, on return, the node's state is guaranteed to be
  // either LOADED_FAVICON (if it was already loaded prior to the call) or
  // LOADING_FAVICON (with the exception of folders, where the call is a no-op).
  const gfx::Image& GetFavicon(const BookmarkNode* node);

  // Returns the type of the favicon for |node|. If the favicon has not yet
  // been loaded, it returns |favicon_base::IconType::kInvalid|.
  favicon_base::IconType GetFaviconType(const BookmarkNode* node);

  // Sets the title of |node|.
  void SetTitle(const BookmarkNode* node, const base::string16& title);

  // Sets the URL of |node|.
  void SetURL(const BookmarkNode* node, const GURL& url);

  // Sets the date added time of |node|.
  void SetDateAdded(const BookmarkNode* node, base::Time date_added);

  // Returns the set of nodes with the |url|.
  void GetNodesByURL(const GURL& url, std::vector<const BookmarkNode*>* nodes);

  // Returns the most recently added user node for the |url|; urls from any
  // nodes that are not editable by the user are never returned by this call.
  // Returns NULL if |url| is not bookmarked.
  const BookmarkNode* GetMostRecentlyAddedUserNodeForURL(const GURL& url);

  // Returns true if there are bookmarks, otherwise returns false.
  bool HasBookmarks();

  // Returns true is there is no user created bookmarks or folders.
  bool HasNoUserCreatedBookmarksOrFolders();

  // Returns true if the specified URL is bookmarked.
  bool IsBookmarked(const GURL& url);

  // Returns, by reference in |bookmarks|, the set of bookmarked urls and their
  // titles. This returns the unique set of URLs. For example, if two bookmarks
  // reference the same URL only one entry is added not matter the titles are
  // same or not.
  void GetBookmarks(std::vector<UrlAndTitle>* urls);

  // Adds a new folder node at the specified position with the given |guid| and
  // |meta_info|. If a GUID is provided, it must be a valid version 4 GUID,
  // otherwise a new one is generated to replace it.
  const BookmarkNode* AddFolder(
      const BookmarkNode* parent,
      size_t index,
      const base::string16& title,
      const BookmarkNode::MetaInfoMap* meta_info = nullptr,
      base::Optional<std::string> guid = base::nullopt);

  // Adds a url at the specified position with the given |creation_time|,
  // |meta_info| and |guid|. If a GUID is provided, it must be a valid version 4
  // GUID, otherwise a new one is generated to replace it.
  const BookmarkNode* AddURL(
      const BookmarkNode* parent,
      size_t index,
      const base::string16& title,
      const GURL& url,
      const BookmarkNode::MetaInfoMap* meta_info = nullptr,
      base::Optional<base::Time> creation_time = base::nullopt,
      base::Optional<std::string> guid = base::nullopt);

  // Sorts the children of |parent|, notifying observers by way of the
  // BookmarkNodeChildrenReordered method.
  void SortChildren(const BookmarkNode* parent);

  // Order the children of |parent| as specified in |ordered_nodes|.  This
  // function should only be used to reorder the child nodes of |parent| and
  // is not meant to move nodes between different parent. Notifies observers
  // using the BookmarkNodeChildrenReordered method.
  void ReorderChildren(const BookmarkNode* parent,
                       const std::vector<const BookmarkNode*>& ordered_nodes);

  // Sets the date when the folder was modified.
  void SetDateFolderModified(const BookmarkNode* node, const base::Time time);

  // Resets the 'date modified' time of the node to 0. This is used during
  // importing to exclude the newly created folders from showing up in the
  // combobox of most recently modified folders.
  void ResetDateFolderModified(const BookmarkNode* node);

  // Returns up to |max_count| of bookmarks containing each term from |text|
  // in either the title or the URL. It uses default matching algorithm.
  void GetBookmarksMatching(const base::string16& text,
                            size_t max_count,
                            std::vector<TitledUrlMatch>* matches);

  // Returns up to |max_count| of bookmarks containing each term from |text|
  // in either the title or the URL.
  void GetBookmarksMatching(const base::string16& text,
                            size_t max_count,
                            query_parser::MatchingAlgorithm matching_algorithm,
                            std::vector<TitledUrlMatch>* matches);

  // Sets the store to NULL, making it so the BookmarkModel does not persist
  // any changes to disk. This is only useful during testing to speed up
  // testing.
  void ClearStore();

  // Returns the next node ID.
  int64_t next_node_id() const { return next_node_id_; }

  // Returns the object responsible for tracking the set of expanded nodes in
  // the bookmark editor.
  BookmarkExpandedStateTracker* expanded_state_tracker() {
    return expanded_state_tracker_.get();
  }

  // Sets/deletes meta info of |node|.
  void SetNodeMetaInfo(const BookmarkNode* node,
                       const std::string& key,
                       const std::string& value);
  void SetNodeMetaInfoMap(const BookmarkNode* node,
                          const BookmarkNode::MetaInfoMap& meta_info_map);
  void DeleteNodeMetaInfo(const BookmarkNode* node,
                          const std::string& key);

  // Adds |key| to the set of meta info keys that are not copied when a node is
  // cloned.
  void AddNonClonedKey(const std::string& key);

  // Returns the set of meta info keys that should not be copied when a node is
  // cloned.
  const std::set<std::string>& non_cloned_keys() const {
    return non_cloned_keys_;
  }

  // Notify BookmarkModel that the favicons for the given page URLs (e.g.
  // http://www.google.com) and the given icon URL (e.g.
  // http://www.google.com/favicon.ico) have changed. It is valid to call
  // OnFaviconsChanged() with non-empty |page_urls| and an empty |icon_url| and
  // vice versa.
  void OnFaviconsChanged(const std::set<GURL>& page_urls,
                         const GURL& icon_url);

  // Returns the client used by this BookmarkModel.
  BookmarkClient* client() const { return client_.get(); }

  void SetUndoDelegate(BookmarkUndoDelegate* undo_delegate);

  base::WeakPtr<BookmarkModel> AsWeakPtr() {
    return weak_factory_.GetWeakPtr();
  }

 private:
  friend class BookmarkCodecTest;
  friend class BookmarkModelFaviconTest;
  friend class BookmarkStorage;
  friend class ScopedGroupBookmarkActions;
  friend class TestBookmarkClient;

  // BookmarkUndoProvider:
  void RestoreRemovedNode(const BookmarkNode* parent,
                          size_t index,
                          std::unique_ptr<BookmarkNode> node) override;

  // Notifies the observers for adding every descedent of |node|.
  void NotifyNodeAddedForAllDescendents(const BookmarkNode* node);

  // Removes the node from internal maps and recurses through all children. If
  // the node is a url, its url is added to removed_urls.
  //
  // This does NOT delete the node.
  void RemoveNodeFromIndexRecursive(BookmarkNode* node);

  // Called when done loading. Updates internal state and notifies observers.
  void DoneLoading(std::unique_ptr<BookmarkLoadDetails> details);

  // Adds the |node| at |parent| in the specified |index| and notifies its
  // observers.
  BookmarkNode* AddNode(BookmarkNode* parent,
                        size_t index,
                        std::unique_ptr<BookmarkNode> node);

  // Adds |node| to |index_| and recursisvely invokes this for all children.
  void AddNodeToIndexRecursive(BookmarkNode* node);

  // Returns true if the parent and index are valid.
  bool IsValidIndex(const BookmarkNode* parent, size_t index, bool allow_end);

  // Notification that a favicon has finished loading. If we can decode the
  // favicon, FaviconLoaded is invoked.
  void OnFaviconDataAvailable(
      BookmarkNode* node,
      favicon_base::IconType icon_type,
      const favicon_base::FaviconImageResult& image_result);

  // Invoked from the node to load the favicon. Requests the favicon from the
  // favicon service.
  void LoadFavicon(BookmarkNode* node, favicon_base::IconType icon_type);

  // Called to notify the observers that the favicon has been loaded.
  void FaviconLoaded(const BookmarkNode* node);

  // If we're waiting on a favicon for node, the load request is canceled.
  void CancelPendingFaviconLoadRequests(BookmarkNode* node);

  // Notifies the observers that a set of changes initiated by a single user
  // action is about to happen and has completed.
  void BeginGroupedChanges();
  void EndGroupedChanges();

  // Generates and returns the next node ID.
  int64_t generate_next_node_id();

  // Sets the maximum node ID to the given value.
  // This is used by BookmarkCodec to report the maximum ID after it's done
  // decoding since during decoding codec assigns node IDs.
  void set_next_node_id(int64_t id) { next_node_id_ = id; }

  BookmarkUndoDelegate* undo_delegate() const;

  std::unique_ptr<BookmarkClient> client_;

  // Whether the initial set of data has been loaded.
  bool loaded_ = false;

  // See |root_| for details.
  std::unique_ptr<BookmarkNode> owned_root_;

  // The root node. This contains the bookmark bar node, the 'other' node and
  // the mobile node as children. The value of |root_| is initially that of
  // |owned_root_|. Once loading has completed, |owned_root_| is destroyed and
  // this is set to url_index_->root(). |owned_root_| is done as lots of
  // existing code assumes the root is non-null while loading.
  BookmarkNode* root_ = nullptr;

  BookmarkPermanentNode* bookmark_bar_node_ = nullptr;
  BookmarkPermanentNode* other_node_ = nullptr;
  BookmarkPermanentNode* mobile_node_ = nullptr;

  // The maximum ID assigned to the bookmark nodes in the model.
  int64_t next_node_id_ = 1;

  // The observers.
  base::ObserverList<BookmarkModelObserver>::Unchecked observers_;

  // Used for loading favicons.
  base::CancelableTaskTracker cancelable_task_tracker_;

  // Reads/writes bookmarks to disk.
  std::unique_ptr<BookmarkStorage> store_;

  std::unique_ptr<TitledUrlIndex> titled_url_index_;

#if DCHECK_IS_ON()
  // GUID index used to verify uniqueness in DCHECK-enabled builds.
  std::set<std::string> guid_index_;
#endif  // DCHECK_IS_ON()

  // Owned by |model_loader_|.
  // WARNING: in some tests this does *not* refer to
  // |ModelLoader::history_bookmark_model_|. This is because some tests
  // directly call DoneLoading().
  // TODO: this is confusing, fix tests not to circumvent ModelLoader.
  scoped_refptr<UrlIndex> url_index_;

  // See description of IsDoingExtensiveChanges above.
  int extensive_changes_ = 0;

  std::unique_ptr<BookmarkExpandedStateTracker> expanded_state_tracker_;

  std::set<std::string> non_cloned_keys_;

  BookmarkUndoDelegate* undo_delegate_ = nullptr;
  std::unique_ptr<BookmarkUndoDelegate> empty_undo_delegate_;

  scoped_refptr<ModelLoader> model_loader_;

  SEQUENCE_CHECKER(sequence_checker_);

  base::WeakPtrFactory<BookmarkModel> weak_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(BookmarkModel);
};

}  // namespace bookmarks

#endif  // COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_MODEL_H_


text:
import webpack from 'webpack';
import path from 'path';
import precss from 'precss';
import autoprefixer from 'autoprefixer';

const rootPath = path.join(__dirname, '../../');

export default {
  entry: [
    path.join(rootPath, 'examples/app.js'),
    'webpack-dev-server/client?http://localhost:8080',
    'webpack/hot/dev-server',
  ],
  output: {
    path: path.join(__dirname),
    filename: 'bundle.js',
    publicPath: '/assets/',
  },
  resolve: {
    alias: {
      myApp: path.join(rootPath, 'src/myApp.js'),
    },
  },
  module: {
    loaders: [
      { test: /\.js$/, exclude: /node_modules/, loader: 'babel' },
      { test: /\.css$/, loaders: ['style', 'css', 'postcss'] },
    ],
  },
  postcss: () => {
    return [
      precss(),
      autoprefixer({
        browsers: [
          'last 2 version',
          'ie >= 10',
        ],
      }),
    ];
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': '"development"',
    }),
    new webpack.HotModuleReplacementPlugin(),
  ],
};


text:
import asyncio
import aiopg

from . import nwdb
from . import core

@core.handler
def set_object(client, key, value):
    """
    Save an arbitrary object for a member under a key. Member must
    be admin in clan.
    """
    client.require_clan_role(client.clan_id, 'Admin')
    value = json.dumps(value)
    with (yield from nwdb.connection()) as conn:
        cursor = yield from conn.cursor()
        yield from cursor.execute("""
        update clan_store set value = %s
        where key = %s and clan_id = %s
        returning id
        """, [value, key, client.clan_id])
        rs = yield from cursor.fetchone()
        if rs is None:
            yield from cursor.execute("""
            insert into clan_store(clan_id, key, value)
            select %s, %s, %ss
            """, [client.clan_id, key, value])

@core.function
def get_object(client, key):
    """
    Retrieves an arbitrary object previously stored by the member under a key.
    """
    client.require_auth()
    with (yield from nwdb.connection()) as conn:
        cursor = yield from conn.cursor()
        yield from cursor.execute("""
        select value from clan_store
        where clan_id = %s and key = %s
        """, [client.clan_id, key])
        rs = yield from cursor.fetchone()
        if rs is not None:
            rs = json.loads(rs[0])
        return rs

@core.function
def get_object_keys(client):
    """
    Retrieves all keys stored by the clan.
    """
    client.require_auth()
    with (yield from nwdb.connection()) as conn:
        cursor = yield from conn.cursor()
        yield from cursor.execute("""
        select key from clan_store
        where clan_id = %s
        """, [client.clan_id])
        rs = yield from cursor.fetchall()
        return list(i[0] for i in rs)

@core.function
def members(client):
    """
    Fetch the members of the clan that the user belongs to.
    """
    client.require_auth()
    rs = yield from nwdb.execute("""
    select A.id, A.handle, A.roles
    from member A
    where A.clan_id = (select clan_id from member where id = %s)
    """, client.member_id)
    return [dict(i) for i in rs]

@core.function
def create(client, clan_name, type):
    """
    Create a new clan.
    """
    client.require_auth()
    with (yield from nwdb.connection()) as conn:
        cursor = yield from conn.cursor()
        try:
            yield from cursor.execute("begin")
            yield from cursor.execute("""
            insert into clan(name, type)
            select %s, %s
            returning id
            """, [clan_name, type])
            rs = yield from cursor.fetchone()
            yield from cursor.execute("""
            update member set clan_id = %s, roles = roles || text('Clan Admin')
            where id = %s
            """,[rs[0], client.member_id])
            yield from cursor.execute("commit")
            return True
        except:
            yield from cursor.execute("rollback")
            return False

@core.function
def leave(client):
    """
    Leave the current clan.
    """
    client.require_auth()
    yield from nwdb.execute("""
    update member set clan_id = null where member_id = %s
    """, [client.member_id])
    return True

@core.function
def join(client, clan_id):
    """
    Join a clan. The member must be approved after this event is sent, by
    a clan admin.
    """
    client.require_auth()
    try:
        yield from nwdb.execute("""
        update member set clan_id = %s, roles = roles || text('Clan Applicant')
        where id = %s
        """, clan_id, client.member_id)
        return True
    except:
        return False

@core.handler
def kick(client, member_id):
    client.require_clan_role(client.clan_id, 'Admin')
    yield from remove_role(client.clan_id, member_id, "Clan Admin")
    with (yield from nwdb.connection()) as conn:
        cursor = yield from conn.cursor()
        yield from cursor.execute("""
        update member set clan_id = null
        where clan_id = %s and id = %s
        """, [client.clan_id, member_id])

@core.function
def list(client):
    """
    Fetch list of clans
    """
    client.require_auth()
    rs = yield from nwdb.execute("""
    select id, name, type from clan
    order by name
    """)
    return [dict(i) for i in rs]

@core.handler
def add_role(client, clan_id, member_id, role):
    client.require_clan_role(clan_id, 'Admin')
    if not role.startswith("Clan "):
        raise ValueException("Role must be prefixed with 'Clan '")
    with (yield from nwdb.connection()) as conn:
        cursor = yield from conn.cursor()
        yield from cursor.execute("""
        select add_role(%s, %s);
        """, member_id, role)

@core.handler
def remove_role(client, clan_id, member_id, role):
    client.require_clan_role(clan_id, 'Admin')
    if not role.startswith("Clan "):
        raise ValueException("Role must be prefixed with 'Clan '")
    with (yield from nwdb.connection()) as conn:
        cursor = yield from conn.cursor()
        yield from cursor.execute("""
        select remove_role(%s, %s);
        """, member_id, role)