text:
// Copyright 2018-present MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <functional>
#include <vector>

#include <bsoncxx/builder/basic/document.hpp>
#include <bsoncxx/json.hpp>
#include <bsoncxx/string/to_string.hpp>
#include <bsoncxx/test_util/catch.hh>
#include <bsoncxx/types.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/collection.hpp>
#include <mongocxx/cursor.hpp>
#include <mongocxx/database.hpp>
#include <mongocxx/options/aggregate.hpp>
#include <mongocxx/options/count.hpp>
#include <mongocxx/options/delete.hpp>
#include <mongocxx/options/distinct.hpp>
#include <mongocxx/options/find.hpp>
#include <mongocxx/options/find_one_and_delete.hpp>
#include <mongocxx/options/find_one_and_replace.hpp>
#include <mongocxx/options/find_one_and_update.hpp>
#include <mongocxx/options/find_one_common_options.hpp>
#include <mongocxx/options/replace.hpp>
#include <mongocxx/options/update.hpp>
#include <mongocxx/result/delete.hpp>
#include <mongocxx/result/insert_many.hpp>
#include <mongocxx/result/insert_one.hpp>
#include <mongocxx/result/replace_one.hpp>
#include <mongocxx/result/update.hpp>
#include <mongocxx/test/spec/operation.hh>

#include <mongocxx/config/private/prelude.hh>

namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
namespace spec {

using namespace mongocxx;
using namespace bsoncxx;

int64_t as_int64(const document::element& el) {
    if (el.type() == type::k_int32) {
        return static_cast<std::int64_t>(el.get_int32().value);
    } else if (el.type() == type::k_int64) {
        return el.get_int64().value;
    }
    REQUIRE(false);
    return 0;
}

pipeline build_pipeline(array::view pipeline_docs) {
    pipeline pipeline{};

    pipeline.append_stages(std::move(pipeline_docs));

    return pipeline;
}

bsoncxx::stdx::optional<read_concern> lookup_read_concern(document::view doc) {
    if (doc["readConcern"] && doc["readConcern"]["level"]) {
        read_concern rc;
        rc.acknowledge_string(string::to_string(doc["readConcern"]["level"].get_string().value));
        return rc;
    }

    return {};
}

bsoncxx::stdx::optional<write_concern> lookup_write_concern(document::view doc) {
    if (doc["writeConcern"] && doc["writeConcern"]["w"]) {
        write_concern wc;
        document::element w = doc["writeConcern"]["w"];
        if (w.type() == bsoncxx::type::k_string) {
            std::string level = string::to_string(w.get_string().value);
            if (level.compare("majority") == 0) {
                wc.acknowledge_level(write_concern::level::k_majority);
            } else if (level.compare("acknowledged") == 0) {
                wc.acknowledge_level(write_concern::level::k_acknowledged);
            } else if (level.compare("unacknowledged") == 0) {
                wc.acknowledge_level(write_concern::level::k_unacknowledged);
            }
        } else if (w.type() == bsoncxx::type::k_int32) {
            wc.nodes(w.get_int32());
        }
        return wc;
    }

    return {};
}

bsoncxx::stdx::optional<read_preference> lookup_read_preference(document::view doc) {
    if (doc["readPreference"] && doc["readPreference"]["mode"]) {
        read_preference rp;
        std::string mode = string::to_string(doc["readPreference"]["mode"].get_string().value);
        if (mode.compare("Primary") == 0) {
            rp.mode(read_preference::read_mode::k_primary);
        } else if (mode.compare("PrimaryPreferred") == 0) {
            rp.mode(read_preference::read_mode::k_primary_preferred);
        } else if (mode.compare("Secondary") == 0) {
            rp.mode(read_preference::read_mode::k_secondary);
        } else if (mode.compare("SecondaryPreferred") == 0) {
            rp.mode(read_preference::read_mode::k_secondary_preferred);
        } else if (mode.compare("Nearest") == 0) {
            rp.mode(read_preference::read_mode::k_nearest);
        }
        return rp;
    }

    return {};
}

client_session* operation_runner::_lookup_session(stdx::string_view key) {
    if (key.compare("session0") == 0) {
        return _session0;
    } else {
        return _session1;
    }

    return nullptr;
}

client_session* operation_runner::_lookup_session(document::view doc) {
    if (doc["session"]) {
        stdx::string_view session_name = doc["session"].get_string().value;
        return _lookup_session(session_name);
    }
    return nullptr;
}

document::value operation_runner::_run_aggregate(document::view operation) {
    document::view arguments = operation["arguments"].get_document().value;
    pipeline pipeline = build_pipeline(arguments["pipeline"].get_array().value);
    options::aggregate options{};

    if (arguments["batchSize"]) {
        options.batch_size(arguments["batchSize"].get_int32().value);
    }

    if (arguments["collation"]) {
        options.collation(arguments["collation"].get_document().value);
    }

    _set_collection_options(operation);

    stdx::optional<cursor> result_cursor;
    client_session* session = _lookup_session(operation["arguments"].get_document().value);

    if (operation["object"] &&
        operation["object"].get_string().value == stdx::string_view{"database"}) {
        REQUIRE(_db);

        // Run on the database
        if (session) {
            result_cursor.emplace(_db->aggregate(*session, pipeline, options));
        } else {
            result_cursor.emplace(_db->aggregate(pipeline, options));
        }
    } else {
        // Run on the collection
        if (session) {
            result_cursor.emplace(_coll->aggregate(*session, pipeline, options));
        } else {
            result_cursor.emplace(_coll->aggregate(pipeline, options));
        }
    }

    auto result = builder::basic::document{};
    result.append(builder::basic::kvp("result", [&result_cursor](builder::basic::sub_array array) {
        for (auto&& document : *result_cursor) {
            array.append(document);
        }
    }));

    return result.extract();
}

document::value operation_runner::_run_distinct(document::view operation) {
    document::view arguments = operation["arguments"].get_document().value;
    document::view filter{};

    if (arguments["filter"]) {
        filter = arguments["filter"].get_document().value;
    }

    bsoncxx::stdx::string_view field_name = arguments["fieldName"].get_string().value;

    options::distinct options{};

    if (arguments["collation"]) {
        options.collation(arguments["collation"].get_document().value);
    }

    stdx::optional<cursor> result_cursor;
    if (client_session* session = _lookup_session(operation["arguments"].get_document().value)) {
        result_cursor.emplace(_coll->distinct(*session, field_name, filter, options));
    } else {
        result_cursor.emplace(_coll->distinct(field_name, filter, options));
    }

    auto result = builder::basic::document{};
    result.append(builder::basic::kvp("result", [&result_cursor](builder::basic::sub_array array) {
        for (auto&& result_doc : *result_cursor) {
            for (auto&& value : result_doc["values"].get_array().value) {
                array.append(value.get_value());
            }
        }
    }));

    return result.extract();
}

document::value operation_runner::_run_find(document::view operation) {
    document::view arguments = operation["arguments"].get_document().value;
    document::value empty_filter = builder::basic::make_document();
    document::view filter;
    if (arguments["filter"]) {
        filter = arguments["filter"].get_document().value;
    } else {
        filter = empty_filter.view();
    }
    options::find options{};

    if (arguments["batchSize"]) {
        options.batch_size(static_cast<std::int32_t>(as_int64(arguments["batchSize"])));
    }

    if (arguments["collation"]) {
        options.collation(arguments["collation"].get_document().value);
    }

    if (arguments["limit"]) {
        options.limit(as_int64(arguments["limit"]));
    }

    if (arguments["skip"]) {
        options.skip(as_int64(arguments["skip"]));
    }

    if (arguments["sort"]) {
        options.sort(arguments["sort"].get_document().value);
    }

    if (arguments["allowDiskUse"]) {
        options.allow_disk_use(arguments["allowDiskUse"].get_bool().value);
    }

    if (arguments["modifiers"]) {
        document::view modifiers = arguments["modifiers"].get_document().value;
        if (modifiers["$comment"]) {
            options.comment(modifiers["$comment"].get_string().value);
        }

        if (modifiers["$hint"]) {
            hint my_hint(modifiers["$hint"].get_document().value);
            options.hint(my_hint);
        }

        if (modifiers["$max"]) {
            options.max(modifiers["$max"].get_document().value);
        }

        if (modifiers["$maxTimeMS"]) {
            std::chrono::milliseconds my_millis(modifiers["$maxTimeMS"].get_int32().value);
            options.max_time(my_millis);
        }

        if (modifiers["$min"]) {
            options.min(modifiers["$min"].get_document().value);
        }

        if (modifiers["$returnKey"]) {
            options.return_key(modifiers["$returnKey"].get_bool().value);
        }

        if (modifiers["$showDiskLoc"]) {
            options.show_record_id(modifiers["$showDiskLoc"].get_bool().value);
        }
    }

    stdx::optional<cursor> result_cursor;
    if (client_session* session = _lookup_session(operation["arguments"].get_document().value)) {
        result_cursor.emplace(_coll->find(*session, filter, options));
    } else {
        result_cursor.emplace(_coll->find(filter, options));
    }

    auto result = builder::basic::document{};
    result.append(builder::basic::kvp("result", [&result_cursor](builder::basic::sub_array array) {
        for (auto&& document : *result_cursor) {
            array.append(document);
        }
    }));

    return result.extract();
}

document::value operation_runner::_run_delete_many(document::view operation) {
    document::view arguments = operation["arguments"].get_document().value;
    document::view filter = arguments["filter"].get_document().value;
    options::delete_options options{};

    if (arguments["collation"]) {
        options.collation(arguments["collation"].get_document().value);
    }

    if (arguments["hint"]) {
        if (arguments["hint"].type() == bsoncxx::v_noabi::type::k_string)
            options.hint(hint{arguments["hint"].get_string().value});
        else
            options.hint(hint{arguments["hint"].get_document().value});
    }

    auto result = builder::basic::document{};
    std::int32_t deleted_count = 0;

    if (client_session* session = _lookup_session(operation["arguments"].get_document().value)) {
        if (auto delete_result = _coll->delete_many(*session, filter, options)) {
            deleted_count = delete_result->deleted_count();
        }
    } else {
        if (auto delete_result = _coll->delete_many(filter, options)) {
            deleted_count = delete_result->deleted_count();
        }
    }

    result.append(
        builder::basic::kvp("result", [deleted_count](builder::basic::sub_document subdoc) {
            subdoc.append(builder::basic::kvp("deletedCount", deleted_count));
        }));

    return result.extract();
}

document::value operation_runner::_run_delete_one(document::view operation) {
    document::view arguments = operation["arguments"].get_document().value;
    document::view filter = arguments["filter"].get_document().value;
    options::delete_options options{};

    if (arguments["collation"]) {
        options.collation(arguments["collation"].get_document().value);
    }

    if (arguments["hint"]) {
        if (arguments["hint"].type() == bsoncxx::v_noabi::type::k_string)
            options.hint(hint{arguments["hint"].get_string().value});
        else
            options.hint(hint{arguments["hint"].get_document().value});
    }

    auto result = builder::basic::document{};
    std::int32_t deleted_count = 0;

    if (client_session* session = _lookup_session(operation["arguments"].get_document().value)) {
        if (auto delete_result = _coll->delete_one(*session, filter, options)) {
            deleted_count = delete_result->deleted_count();
        }
    } else {
        if (auto delete_result = _coll->delete_one(filter, options)) {
            deleted_count = delete_result->deleted_count();
        }
    }

    result.append(
        builder::basic::kvp("result", [deleted_count](builder::basic::sub_document subdoc) {
            subdoc.append(builder::basic::kvp("deletedCount", deleted_count));
        }));

    return result.extract();
}

document::value operation_runner::_run_find_one_and_delete(document::view operation) {
    document::view arguments = operation["arguments"].get_document().value;
    document::view filter = arguments["filter"].get_document().value;
    options::find_one_and_delete options{};

    if (arguments["collation"]) {
        options.collation(arguments["collation"].get_document().value);
    }

    if (arguments["hint"]) {
        if (arguments["hint"].type() == bsoncxx::v_noabi::type::k_string)
            options.hint(hint{arguments["hint"].get_string().value});
        else
            options.hint(hint{arguments["hint"].get_document().value});
    }

    if (arguments["hint"]) {
        if (arguments["hint"].type() == bsoncxx::v_noabi::type::k_string)
            options.hint(hint{arguments["hint"].get_string().value});
        else
            options.hint(hint{arguments["hint"].get_document().value});
    }

    if (arguments["projection"]) {
        options.projection(arguments["projection"].get_document().value);
    }

    if (arguments["sort"]) {
        options.sort(arguments["sort"].get_document().value);
    }

    auto result = builder::basic::document{};
    stdx::optional<document::value> document;
    if (client_session* session = _lookup_session(operation["arguments"].get_document().value)) {
        document = _coll->find_one_and_delete(*session, filter, options);
    } else {
        document = _coll->find_one_and_delete(filter, options);
    }

    // Server versions below 3.0 sometimes return an empty document rather than null when no
    // documents match.
    if (document && !(document->view().empty())) {
        result.append(builder::basic::kvp("result", *document));
    } else {
        result.append(builder::basic::kvp("result", types::b_null{}));
    }

    return result.extract();
}

document::value operation_runner::_run_find_one(document::view operation) {
    auto arguments = operation["arguments"].get_document().value;
    auto filter = arguments["filter"].get_document().value;

    builder::basic::document result{};
    auto document = _coll->find_one(filter);

    // Server versions below 3.0 sometimes return an empty document rather than null when no
    // documents match.
    if (document && !(document->view().empty())) {
        result.append(builder::basic::kvp("result", *document));
    } else {
        result.append(builder::basic::kvp("result", types::b_null{}));
    }

    return result.extract();
}

document::value operation_runner::_run_find_one_and_replace(document::view operation) {
    document::view arguments = operation["arguments"].get_document().value;
    document::view filter = arguments["filter"].get_document().value;
    document::view replacement = arguments["replacement"].get_document().value;
    options::find_one_and_replace options{};

    if (arguments["collation"]) {
        options.collation(arguments["collation"].get_document().value);
    }

    if (arguments["hint"]) {
        if (arguments["hint"].type() == bsoncxx::v_noabi::type::k_string)
            options.hint(hint{arguments["hint"].get_string().value});
        else
            options.hint(hint{arguments["hint"].get_document().value});
    }

    if (arguments["projection"]) {
        options.projection(arguments["projection"].get_document().value);
    }

    if (arguments["returnDocument"]) {
        std::string return_document =
            bsoncxx::string::to_string(arguments["returnDocument"].get_string().value);

        if (return_document == "After") {
            options.return_document(options::return_document::k_after);
        }

        if (return_document == "Before") {
            options.return_document(options::return_document::k_before);
        }
    }

    if (arguments["sort"]) {
        options.sort(arguments["sort"].get_document().value);
    }

    if (arguments["upsert"]) {
        options.upsert(arguments["upsert"].get_bool().value);
    }

    auto result = builder::basic::document{};
    stdx::optional<document::value> document;
    if (client_session* session = _lookup_session(operation["arguments"].get_document().value)) {
        document = _coll->find_one_and_replace(*session, filter, replacement, options);
    } else {
        document = _coll->find_one_and_replace(filter, replacement, options);
    }

    // Server versions below 3.0 sometimes return an empty document rather than null when no
    // documents match.
    if (document && !(document->view().empty())) {
        result.append(builder::basic::kvp("result", *document));
    } else {
        result.append(builder::basic::kvp("result", types::b_null{}));
    }

    return result.extract();
}

document::value operation_runner::_run_find_one_and_update(document::view operation) {
    document::view arguments = operation["arguments"].get_document().value;
    document::view filter = arguments["filter"].get_document().value;
    options::find_one_and_update options{};

    if (arguments["collation"]) {
        options.collation(arguments["collation"].get_document().value);
    }

    if (arguments["hint"]) {
        if (arguments["hint"].type() == bsoncxx::v_noabi::type::k_string)
            options.hint(hint{arguments["hint"].get_string().value});
        else
            options.hint(hint{arguments["hint"].get_document().value});
    }

    if (arguments["projection"]) {
        options.projection(arguments["projection"].get_document().value);
    }

    if (arguments["arrayFilters"]) {
        options.array_filters(arguments["arrayFilters"].get_array().value);
    }

    if (arguments["returnDocument"]) {
        std::string return_document =
            bsoncxx::string::to_string(arguments["returnDocument"].get_string().value);

        if (return_document == "After") {
            options.return_document(options::return_document::k_after);
        }

        if (return_document == "Before") {
            options.return_document(options::return_document::k_before);
        }
    }

    if (arguments["sort"]) {
        options.sort(arguments["sort"].get_document().value);
    }

    if (arguments["upsert"]) {
        options.upsert(arguments["upsert"].get_bool().value);
    }

    auto result = builder::basic::document{};
    stdx::optional<document::value> document;
    client_session* session = _lookup_session(operation["arguments"].get_document().value);

    switch (arguments["update"].type()) {
        case bsoncxx::type::k_document: {
            document::view update = arguments["update"].get_document().value;
            if (session) {
                document = _coll->find_one_and_update(*session, filter, update, options);
            } else {
                document = _coll->find_one_and_update(filter, update, options);
            }
            break;
        }
        case bsoncxx::type::k_array: {
            pipeline update = build_pipeline(arguments["update"].get_array().value);
            if (session) {
                document = _coll->find_one_and_update(*session, filter, update, options);
            } else {
                document = _coll->find_one_and_update(filter, update, options);
            }
            break;
        }
        default:
            throw std::logic_error{"update must be a document or an array"};
    }

    // Server versions below 3.0 sometimes return an empty document rather than null when no
    // documents match.
    if (document && !(document->view().empty())) {
        result.append(builder::basic::kvp("result", *document));
    } else {
        result.append(builder::basic::kvp("result", types::b_null{}));
    }

    return result.extract();
}

document::value operation_runner::_run_insert_many(document::view operation) {
    using bsoncxx::builder::basic::kvp;
    using bsoncxx::builder::basic::make_document;
    document::view arguments = operation["arguments"].get_document().value;
    array::view documents = arguments["documents"].get_array().value;
    std::vector<document::view> documents_to_insert{};
    options::insert insert_options;

    if (arguments["options"]) {
        document::view options = arguments["options"].get_document().value;
        if (options["ordered"]) {
            insert_options.ordered(options["ordered"].get_bool().value);
        }
    }

    for (auto&& element : documents) {
        documents_to_insert.push_back(element.get_document().value);
    }

    stdx::optional<result::insert_many> insert_many_result;
    if (client_session* session = _lookup_session(operation["arguments"].get_document().value)) {
        insert_many_result = _coll->insert_many(*session, documents_to_insert, insert_options);
    } else {
        insert_many_result = _coll->insert_many(documents_to_insert, insert_options);
    }
    std::map<size_t, document::element> inserted_ids{};

    if (insert_many_result) {
        inserted_ids = insert_many_result->inserted_ids();
    }

    auto result = builder::basic::document{};
    bsoncxx::builder::basic::document inserted_ids_builder;

    for (auto&& id_pair : inserted_ids) {
        inserted_ids_builder.append(kvp(std::to_string(id_pair.first), id_pair.second.get_value()));
    }

    result.append(kvp("result", make_document(kvp("insertedIds", inserted_ids_builder.extract()))));
    return result.extract();
}

document::value operation_runner::_run_insert_one(document::view operation) {
    document::view arguments = operation["arguments"].get_document().value;
    document::view document = arguments["document"].get_document().value;

    options::insert opts{};
    if (arguments["bypassDocumentValidation"]) {
        opts.bypass_document_validation(true);
    }

    stdx::optional<result::insert_one> insert_one_result;
    if (client_session* session = _lookup_session(arguments)) {
        insert_one_result = _coll->insert_one(*session, document, opts);
    } else {
        insert_one_result = _coll->insert_one(document, opts);
    }

    types::bson_value::view inserted_id{types::b_null{}};

    if (insert_one_result) {
        inserted_id = insert_one_result->inserted_id();
    }

    auto result = builder::basic::document{};
    result.append(builder::basic::kvp("result", [inserted_id](builder::basic::sub_document subdoc) {
        subdoc.append(builder::basic::kvp("insertedId", inserted_id));
    }));

    return result.extract();
}

document::value operation_runner::_run_replace_one(document::view operation) {
    document::view arguments = operation["arguments"].get_document().value;
    document::view filter = arguments["filter"].get_document().value;
    document::view replacement = arguments["replacement"].get_document().value;
    options::replace options{};

    if (arguments["collation"]) {
        options.collation(arguments["collation"].get_document().value);
    }

    if (arguments["hint"]) {
        if (arguments["hint"].type() == bsoncxx::v_noabi::type::k_string)
            options.hint(hint{arguments["hint"].get_string().value});
        else
            options.hint(hint{arguments["hint"].get_document().value});
    }

    if (arguments["upsert"]) {
        options.upsert(arguments["upsert"].get_bool().value);
    }

    std::int32_t matched_count = 0;
    bsoncxx::stdx::optional<std::int32_t> modified_count;
    std::int32_t upserted_count = 0;
    stdx::optional<result::replace_one> replace_result;
    if (client_session* session = _lookup_session(operation["arguments"].get_document().value)) {
        replace_result = _coll->replace_one(*session, filter, replacement, options);
    } else {
        replace_result = _coll->replace_one(filter, replacement, options);
    }
    bsoncxx::stdx::optional<types::bson_value::view> upserted_id{};

    if (replace_result) {
        matched_count = replace_result->matched_count();

        // Server versions below 2.4 do not return an `nModified` count.
        try {
            modified_count = replace_result->modified_count();
        } catch (const std::exception& e) {
        }

        upserted_count = replace_result->result().upserted_count();

        if (auto upserted_element = replace_result->upserted_id()) {
            upserted_id = upserted_element->get_value();
        }
    }

    auto result = builder::basic::document{};
    result.append(builder::basic::kvp(
        "result",
        [matched_count, modified_count, upserted_count, upserted_id](
            builder::basic::sub_document subdoc) {
            subdoc.append(builder::basic::kvp("matchedCount", matched_count));

            if (modified_count) {
                subdoc.append(builder::basic::kvp("modifiedCount", *modified_count));
            }

            subdoc.append(builder::basic::kvp("upsertedCount", upserted_count));

            if (upserted_id) {
                subdoc.append(builder::basic::kvp("upsertedId", *upserted_id));
            }
        }));

    return result.extract();
}

document::value operation_runner::_run_update_many(document::view operation) {
    document::view arguments = operation["arguments"].get_document().value;
    document::view filter = arguments["filter"].get_document().value;
    options::update options{};

    if (arguments["collation"]) {
        options.collation(arguments["collation"].get_document().value);
    }

    if (arguments["hint"]) {
        if (arguments["hint"].type() == bsoncxx::v_noabi::type::k_string)
            options.hint(hint{arguments["hint"].get_string().value});
        else
            options.hint(hint{arguments["hint"].get_document().value});
    }

    if (arguments["upsert"]) {
        options.upsert(arguments["upsert"].get_bool().value);
    }

    if (arguments["arrayFilters"]) {
        options.array_filters(arguments["arrayFilters"].get_array().value);
    }

    std::int32_t matched_count = 0;
    bsoncxx::stdx::optional<std::int32_t> modified_count;
    std::int32_t upserted_count = 0;
    stdx::optional<result::update> update_result;
    client_session* session = _lookup_session(operation["arguments"].get_document().value);

    switch (arguments["update"].type()) {
        case bsoncxx::type::k_document: {
            document::view update = arguments["update"].get_document().value;
            if (session) {
                update_result = _coll->update_many(*session, filter, update, options);
            } else {
                update_result = _coll->update_many(filter, update, options);
            }
            break;
        }
        case bsoncxx::type::k_array: {
            pipeline update = build_pipeline(arguments["update"].get_array().value);
            if (session) {
                update_result = _coll->update_many(*session, filter, update, options);
            } else {
                update_result = _coll->update_many(filter, update, options);
            }
            break;
        }
        default:
            throw std::logic_error{"update must be a document or an array"};
    }

    bsoncxx::stdx::optional<types::bson_value::view> upserted_id{};

    if (update_result) {
        matched_count = update_result->matched_count();

        // Server versions below 2.4 do not return an `nModified` count.
        try {
            modified_count = update_result->modified_count();
        } catch (const std::exception& e) {
        }

        upserted_count = update_result->result().upserted_count();

        if (auto upserted_element = update_result->upserted_id()) {
            upserted_id = upserted_element->get_value();
        }
    }

    auto result = builder::basic::document{};
    result.append(builder::basic::kvp(
        "result",
        [matched_count, modified_count, upserted_count, upserted_id](
            builder::basic::sub_document subdoc) {
            subdoc.append(builder::basic::kvp("matchedCount", matched_count));

            if (modified_count) {
                subdoc.append(builder::basic::kvp("modifiedCount", *modified_count));
            }

            subdoc.append(builder::basic::kvp("upsertedCount", upserted_count));

            if (upserted_id) {
                subdoc.append(builder::basic::kvp("upsertedId", *upserted_id));
            }
        }));

    return result.extract();
}

document::value operation_runner::_run_update_one(document::view operation) {
    document::view arguments = operation["arguments"].get_document().value;
    document::view filter = arguments["filter"].get_document().value;
    options::update options{};

    if (arguments["collation"]) {
        options.collation(arguments["collation"].get_document().value);
    }

    if (arguments["hint"]) {
        if (arguments["hint"].type() == bsoncxx::v_noabi::type::k_string)
            options.hint(hint{arguments["hint"].get_string().value});
        else
            options.hint(hint{arguments["hint"].get_document().value});
    }
    if (arguments["upsert"]) {
        options.upsert(arguments["upsert"].get_bool().value);
    }

    if (arguments["arrayFilters"]) {
        options.array_filters(arguments["arrayFilters"].get_array().value);
    }

    std::int32_t matched_count = 0;
    bsoncxx::stdx::optional<std::int32_t> modified_count;
    std::int32_t upserted_count = 0;
    stdx::optional<result::update> update_result;
    client_session* session = _lookup_session(operation["arguments"].get_document().value);

    switch (arguments["update"].type()) {
        case bsoncxx::type::k_document: {
            document::view update = arguments["update"].get_document().value;
            if (session) {
                update_result = _coll->update_one(*session, filter, update, options);
            } else {
                update_result = _coll->update_one(filter, update, options);
            }
            break;
        }
        case bsoncxx::type::k_array: {
            pipeline update = build_pipeline(arguments["update"].get_array().value);
            if (session) {
                update_result = _coll->update_one(*session, filter, update, options);
            } else {
                update_result = _coll->update_one(filter, update, options);
            }
            break;
        }
        default:
            throw std::logic_error{"update must be a document or an array"};
    }

    bsoncxx::stdx::optional<types::bson_value::view> upserted_id{};

    if (update_result) {
        matched_count = update_result->matched_count();

        // Server versions below 2.4 do not return an `nModified` count.
        try {
            modified_count = update_result->modified_count();
        } catch (const std::exception& e) {
        }

        upserted_count = update_result->result().upserted_count();

        if (auto upserted_element = update_result->upserted_id()) {
            upserted_id = upserted_element->get_value();
        }
    }

    auto result = builder::basic::document{};
    result.append(builder::basic::kvp(
        "result",
        [matched_count, modified_count, upserted_count, upserted_id](
            builder::basic::sub_document subdoc) {
            subdoc.append(builder::basic::kvp("matchedCount", matched_count));

            if (modified_count) {
                subdoc.append(builder::basic::kvp("modifiedCount", *modified_count));
            }

            subdoc.append(builder::basic::kvp("upsertedCount", upserted_count));

            if (upserted_id) {
                subdoc.append(builder::basic::kvp("upsertedId", *upserted_id));
            }
        }));

    return result.extract();
}

void operation_runner::_set_collection_options(document::view operation) {
    if (!operation["collectionOptions"]) {
        return;
    }

    document::view options = operation["collectionOptions"].get_document().value;

    if (options["writeConcern"]) {
        write_concern w;
        document::view write_concern_options = options["writeConcern"].get_document().value;

        // Empty writeConcern document means use the default.
        if (!write_concern_options.empty()) {
            REQUIRE(write_concern_options["w"]);

            int32_t w_option = write_concern_options["w"].get_int32().value;
            w.nodes(w_option);
        }
        _coll->write_concern(w);
    }

    if (options["readConcern"]) {
        document::view read_concern_options = options["readConcern"].get_document().value;
        read_concern rc;

        // Empty readConcern document means use the default.
        if (!read_concern_options.empty()) {
            REQUIRE(read_concern_options["level"]);

            rc.acknowledge_string(read_concern_options["level"].get_string().value);
        }
        _coll->read_concern(rc);
    }
}

template <typename T>
T _build_update_model(document::view arguments) {
    document::view filter = arguments["filter"].get_document().value;

    switch (arguments["update"].type()) {
        case bsoncxx::type::k_document: {
            return T(filter, arguments["update"].get_document().value);
        }
        case bsoncxx::type::k_array: {
            pipeline update = build_pipeline(arguments["update"].get_array().value);
            return T(filter, update);
        }
        default:
            throw std::logic_error{"update must be a document or an array"};
    }
}

document::value operation_runner::_run_bulk_write(document::view operation) {
    using bsoncxx::builder::basic::kvp;
    using bsoncxx::builder::basic::make_document;

    options::bulk_write options;
    std::vector<model::write> writes;

    _set_collection_options(operation);

    auto arguments = operation["arguments"].get_document().value;
    if (arguments["options"]) {
        document::view options_doc = arguments["options"].get_document().value;
        if (options_doc["ordered"]) {
            options.ordered(options_doc["ordered"].get_bool().value);
        }
    }
    auto requests = arguments["requests"].get_array().value;
    for (auto&& request_element : requests) {
        auto request = request_element.get_document().value;
        auto request_arguments = request["arguments"].get_document().value;
        auto operation_name = request["name"].get_string().value;

        if (operation_name.compare("updateOne") == 0) {
            auto update_one = _build_update_model<model::update_one>(request_arguments);

            if (request_arguments["hint"]) {
                if (request_arguments["hint"].type() == bsoncxx::v_noabi::type::k_string)
                    update_one.hint(hint{request_arguments["hint"].get_string().value});
                else
                    update_one.hint(hint{request_arguments["hint"].get_document().value});
            }

            if (request_arguments["collation"]) {
                update_one.collation(request_arguments["collation"].get_document().value);
            }

            if (request_arguments["upsert"]) {
                update_one.upsert(request_arguments["upsert"].get_bool().value);
            }

            if (request_arguments["arrayFilters"]) {
                update_one.array_filters(request_arguments["arrayFilters"].get_array().value);
            }

            writes.emplace_back(update_one);
        } else if (operation_name.compare("updateMany") == 0) {
            auto update_many = _build_update_model<model::update_many>(request_arguments);

            if (request_arguments["hint"]) {
                if (request_arguments["hint"].type() == bsoncxx::v_noabi::type::k_string)
                    update_many.hint(hint{request_arguments["hint"].get_string().value});
                else
                    update_many.hint(hint{request_arguments["hint"].get_document().value});
            }

            if (request_arguments["collation"]) {
                update_many.collation(request_arguments["collation"].get_document().value);
            }

            if (request_arguments["upsert"]) {
                update_many.upsert(request_arguments["upsert"].get_bool().value);
            }

            if (request_arguments["arrayFilters"]) {
                update_many.array_filters(request_arguments["arrayFilters"].get_array().value);
            }

            writes.emplace_back(update_many);
        } else if (operation_name.compare("replaceOne") == 0) {
            document::view filter = request_arguments["filter"].get_document().value;
            document::view replacement = request_arguments["replacement"].get_document().value;
            model::replace_one replace_one(filter, replacement);
            if (request_arguments["hint"]) {
                if (request_arguments["hint"].type() == bsoncxx::v_noabi::type::k_string)
                    replace_one.hint(hint{request_arguments["hint"].get_string().value});
                else
                    replace_one.hint(hint{request_arguments["hint"].get_document().value});
            }

            if (request_arguments["collation"]) {
                replace_one.collation(request_arguments["collation"].get_document().value);
            }

            if (request_arguments["upsert"]) {
                replace_one.upsert(request_arguments["upsert"].get_bool().value);
            }

            writes.emplace_back(replace_one);
        } else if (operation_name.compare("insertOne") == 0) {
            document::view document = request_arguments["document"].get_document().value;
            model::insert_one insert_one(document);
            writes.emplace_back(insert_one);
        } else if (operation_name.compare("deleteOne") == 0) {
            document::view filter = request_arguments["filter"].get_document().value;
            model::delete_one delete_one(filter);
            if (request_arguments["hint"]) {
                if (request_arguments["hint"].type() == bsoncxx::v_noabi::type::k_string)
                    delete_one.hint(hint{request_arguments["hint"].get_string().value});
                else
                    delete_one.hint(hint{request_arguments["hint"].get_document().value});
            }

            if (request_arguments["collation"]) {
                delete_one.collation(request_arguments["collation"].get_document().value);
            }

            writes.emplace_back(delete_one);
        } else if (operation_name.compare("deleteMany") == 0) {
            document::view filter = request_arguments["filter"].get_document().value;
            model::delete_many delete_many(filter);
            if (request_arguments["hint"]) {
                if (request_arguments["hint"].type() == bsoncxx::v_noabi::type::k_string)
                    delete_many.hint(hint{request_arguments["hint"].get_string().value});
                else
                    delete_many.hint(hint{request_arguments["hint"].get_document().value});
            }

            if (request_arguments["collation"]) {
                delete_many.collation(request_arguments["collation"].get_document().value);
            }

            writes.emplace_back(delete_many);
        } else {
            /* should not happen. */
            REQUIRE(false);
        }
    }

    std::int32_t deleted_count = 0;
    std::int32_t matched_count = 0;
    std::int32_t modified_count = 0;
    std::int32_t upserted_count = 0;
    result::bulk_write::id_map upserted_ids;
    std::int32_t inserted_count = 0;
    stdx::optional<result::bulk_write> bulk_write_result;
    if (client_session* session = _lookup_session(operation["arguments"].get_document().value)) {
        bulk_write_result = _coll->bulk_write(*session, writes, options);
    } else {
        bulk_write_result = _coll->bulk_write(writes, options);
    }
    if (bulk_write_result) {
        matched_count = bulk_write_result->matched_count();
        modified_count = bulk_write_result->modified_count();
        upserted_count = bulk_write_result->upserted_count();
        upserted_ids = bulk_write_result->upserted_ids();
        inserted_count = bulk_write_result->inserted_count();
        deleted_count = bulk_write_result->deleted_count();
    }
    builder::basic::document upserted_ids_builder;
    for (auto&& index_and_id : upserted_ids) {
        upserted_ids_builder.append(
            kvp(std::to_string(index_and_id.first), index_and_id.second.get_int32().value));
    }
    auto upserted_ids_doc = upserted_ids_builder.extract();
    auto result = bsoncxx::builder::basic::document{};
    // Construct the result document.
    // Note: insertedIds is currently hard coded as an empty document, because result::bulk_write
    // provides no way to see inserted ids. This is compliant with the CRUD spec, as insertedIds
    // are: "NOT REQUIRED: Drivers may choose to not provide this property." So just add an empty
    // document for insertedIds. There are no current bulk write tests testing insert operations.
    // The insertedIds field in current bulk write spec tests is always an empty document.
    result.append(kvp("result",
                      make_document(kvp("matchedCount", matched_count),
                                    kvp("modifiedCount", modified_count),
                                    kvp("upsertedCount", upserted_count),
                                    kvp("deletedCount", deleted_count),
                                    kvp("insertedCount", inserted_count),
                                    kvp("insertedIds", make_document()),
                                    kvp("upsertedIds", upserted_ids_doc))));
    return result.extract();
}

document::value operation_runner::_run_count_documents(document::view operation) {
    document::view arguments = operation["arguments"].get_document().value;
    document::view filter = arguments["filter"].get_document().value;
    options::count options{};

    if (arguments["collation"]) {
        options.collation(arguments["collation"].get_document().value);
    }

    if (arguments["limit"]) {
        options.limit(arguments["limit"].get_int32().value);
    }

    if (arguments["skip"]) {
        options.skip(arguments["skip"].get_int32().value);
    }

    int64_t count;
    if (client_session* session = _lookup_session(operation["arguments"].get_document().value)) {
        count = _coll->count_documents(*session, filter, options);
    } else {
        count = _coll->count_documents(filter, options);
    }

    auto result = builder::basic::document{};

    // The JSON parser reads the counts as int32, so the document will not be equal to the expected
    // result without casting.
    result.append(builder::basic::kvp("result", static_cast<std::int32_t>(count)));

    return result.extract();
}

document::value operation_runner::_run_estimated_document_count(document::view) {
    int64_t count = _coll->estimated_document_count();

    auto result = builder::basic::document{};

    // The JSON parser reads the counts as int32, so the document will not be equal to the expected
    // result without casting.
    result.append(builder::basic::kvp("result", static_cast<std::int32_t>(count)));

    return result.extract();
}

document::value operation_runner::_run_start_transaction(bsoncxx::document::view operation) {
    options::transaction txn_opts;

    if (operation["arguments"] && operation["arguments"]["options"]) {
        document::view opts = operation["arguments"]["options"].get_document();

        if (auto rc = lookup_read_concern(opts)) {
            txn_opts.read_concern(*rc);
        }

        if (auto wc = lookup_write_concern(opts)) {
            txn_opts.write_concern(*wc);
        }

        if (auto rp = lookup_read_preference(opts)) {
            txn_opts.read_preference(*rp);
        }
    }

    auto session = _lookup_session(operation["object"].get_string().value);
    REQUIRE(session);
    session->start_transaction(txn_opts);

    return bsoncxx::builder::basic::make_document();
}

document::value operation_runner::_run_commit_transaction(bsoncxx::document::view operation) {
    auto session = _lookup_session(operation["object"].get_string().value);
    REQUIRE(session);
    session->commit_transaction();
    return bsoncxx::builder::basic::make_document();
}

document::value operation_runner::_run_abort_transaction(bsoncxx::document::view operation) {
    auto session = _lookup_session(operation["object"].get_string().value);
    REQUIRE(session);
    session->abort_transaction();
    return bsoncxx::builder::basic::make_document();
}

document::value operation_runner::_run_run_command(bsoncxx::document::view operation) {
    document::view arguments = operation["arguments"].get_document().value;
    document::view command = arguments["command"].get_document().value;

    stdx::optional<document::value> reply;
    if (client_session* session = _lookup_session(operation["arguments"].get_document().value)) {
        reply = _db->run_command(*session, command);
    } else {
        reply = _db->run_command(command);
    }

    auto result = builder::basic::document{};
    result.append(builder::basic::kvp("result", *reply));

    return result.extract();
}

document::value operation_runner::_run_configure_fail_point(bsoncxx::document::view operation) {
    auto arguments = operation["arguments"].get_document().value;
    auto command = arguments["failPoint"].get_document().value;

    const client_session* session = _lookup_session(arguments);

    read_preference rp;
    uint32_t server_id = session->server_id();
    stdx::optional<document::value> reply = (*_client)["admin"].run_command(command, server_id);

    auto result = builder::basic::document{};
    result.append(builder::basic::kvp("result", *reply));

    return result.extract();
}

document::value operation_runner::_create_index(const document::view& operation) {
    auto arguments = operation["arguments"];
    auto session = _lookup_session(arguments.get_document().value);
    REQUIRE(session);

    auto name = arguments["name"].get_string().value;
    auto keys = arguments["keys"].get_document().value;

    bsoncxx::builder::basic::document opts;
    opts.append(bsoncxx::builder::basic::kvp("name", name));

    return _coll->create_index(*session, keys, opts.extract());
}

operation_runner::operation_runner(collection* coll) : operation_runner(nullptr, coll) {}
operation_runner::operation_runner(database* db,
                                   collection* coll,
                                   client_session* session0,
                                   client_session* session1,
                                   client* client)
    : _coll(coll), _db(db), _session0(session0), _session1(session1), _client(client) {}

document::value operation_runner::run(document::view operation) {
    using namespace bsoncxx::builder::basic;
    bsoncxx::document::value empty_document({});

    stdx::string_view key = operation["name"].get_string().value;
    stdx::string_view object;
    if (operation["object"]) {
        object = operation["object"].get_string().value;
    }

    if (key.compare("aggregate") == 0) {
        return _run_aggregate(operation);
    } else if (key.compare("count") == 0) {
        throw std::logic_error{"count command not supported"};
    } else if (key.compare("countDocuments") == 0) {
        return _run_count_documents(operation);
    } else if (key.compare("estimatedDocumentCount") == 0) {
        return _run_estimated_document_count(operation);
    } else if (key.compare("distinct") == 0) {
        return _run_distinct(operation);
    } else if (key.compare("find") == 0) {
        return _run_find(operation);
    } else if (key.compare("deleteMany") == 0) {
        return _run_delete_many(operation);
    } else if (key.compare("deleteOne") == 0) {
        return _run_delete_one(operation);
    } else if (key.compare("findOne") == 0) {
        return _run_find_one(operation);
    } else if (key.compare("findOneAndDelete") == 0) {
        return _run_find_one_and_delete(operation);
    } else if (key.compare("findOneAndReplace") == 0) {
        return _run_find_one_and_replace(operation);
    } else if (key.compare("findOneAndUpdate") == 0) {
        return _run_find_one_and_update(operation);
    } else if (key.compare("insertMany") == 0) {
        return _run_insert_many(operation);
    } else if (key.compare("insertOne") == 0) {
        return _run_insert_one(operation);
    } else if (key.compare("replaceOne") == 0) {
        return _run_replace_one(operation);
    } else if (key.compare("updateMany") == 0) {
        return _run_update_many(operation);
    } else if (key.compare("updateOne") == 0) {
        return _run_update_one(operation);
    } else if (key.compare("bulkWrite") == 0) {
        return _run_bulk_write(operation);
    } else if (key.compare("startTransaction") == 0) {
        return _run_start_transaction(operation);
    } else if (key.compare("commitTransaction") == 0) {
        return _run_commit_transaction(operation);
    } else if (key.compare("abortTransaction") == 0) {
        return _run_abort_transaction(operation);
    } else if (key.compare("runCommand") == 0) {
        return _run_run_command(operation);
    } else if (key.compare("targetedFailPoint") == 0) {
        return _run_configure_fail_point(operation);
    } else if (key.compare("assertSessionPinned") == 0) {
        const client_session* session =
            _lookup_session(operation["arguments"].get_document().value);
        REQUIRE(session->server_id());
        return empty_document;
    } else if (key.compare("operationassertSessionUnpinned") == 0) {
        const client_session* session =
            _lookup_session(operation["arguments"].get_document().value);
        REQUIRE(!session->server_id());
        return empty_document;
    } else if (key.compare("watch") == 0) {
        if (object.compare("collection") == 0) {
            _coll->watch();
        } else if (object.compare("database") == 0) {
            _db->watch();
        } else if (object.compare("client") == 0) {
            _client->watch();
        } else {
            throw std::logic_error{"unsupported operation object: " + string::to_string(object)};
        }
        return empty_document;
    } else if (key.compare("rename") == 0) {
        _coll->rename(operation["arguments"]["to"].get_string().value);
        return empty_document;
    } else if (key.compare("drop") == 0) {
        _coll->drop();
        return empty_document;
    } else if (key.compare("dropCollection") == 0) {
        auto collection_name = operation["arguments"]["collection"].get_string().value;
        _db->collection(collection_name).drop();
        return empty_document;
    } else if (key.compare("listCollectionNames") == 0) {
        _db->list_collection_names();
        return empty_document;
    } else if (key.compare("listCollectionObjects") == 0) {
        throw std::logic_error("listCollectionObjects is not implemented in mongocxx");
    } else if (key.compare("listCollections") == 0) {
        _db->list_collections();
        return empty_document;
    } else if (key.compare("listDatabases") == 0) {
        _client->list_databases().begin(); /* calling begin() iterates the cursor */
        return empty_document;
    } else if (key.compare("listDatabaseNames") == 0) {
        _client->list_database_names();
        return empty_document;
    } else if (key.compare("listIndexes") == 0) {
        _coll->list_indexes().begin(); /* calling begin() iterates the cursor */
        return empty_document;
    } else if (key.compare("download") == 0) {
        std::ostream null_stream(nullptr); /* no need to store output */
        auto bucket = _db->gridfs_bucket();
        bucket.download_to_stream(operation["arguments"]["id"].get_value(), &null_stream);

        return empty_document;
    } else if (key.compare("createCollection") == 0) {
        auto collection_name = operation["arguments"]["collection"].get_string().value;
        auto session = _lookup_session(operation["arguments"].get_document().value);
        REQUIRE(session);

        _db->create_collection(*session, collection_name);
        return empty_document;
    } else if (key.compare("assertCollectionNotExists") == 0) {
        auto collection_name = operation["arguments"]["collection"].get_string().value;
        client client{uri{}};
        REQUIRE_FALSE(client[_db->name()].has_collection(collection_name));
        return empty_document;
    } else if (key.compare("assertCollectionExists") == 0) {
        auto collection_name = operation["arguments"]["collection"].get_string().value;
        client client{uri{}};
        REQUIRE(client[_db->name()].has_collection(collection_name));
        return empty_document;
    } else if (key.compare("createIndex") == 0) {
        return _create_index(operation);
    } else if (key.compare("assertIndexNotExists") == 0) {
        client client{uri{}};
        auto cursor = client[_db->name()][_coll->name()].list_indexes();

        REQUIRE(cursor.end() ==
                std::find_if(cursor.begin(),
                             cursor.end(),
                             [operation](bsoncxx::v_noabi::document::view doc) {
                                 return (doc["name"].get_string() ==
                                         operation["arguments"]["index"].get_string());
                             }));

        return empty_document;
    } else if (key.compare("assertIndexExists") == 0) {
        client client{uri{}};
        auto cursor = client[_db->name()][_coll->name()].list_indexes();

        REQUIRE(cursor.end() !=
                std::find_if(cursor.begin(),
                             cursor.end(),
                             [operation](bsoncxx::v_noabi::document::view doc) {
                                 return (doc["name"].get_string() ==
                                         operation["arguments"]["index"].get_string());
                             }));

        return empty_document;
    } else {
        throw std::logic_error{"unsupported operation: " + string::to_string(key)};
    }
}

}  // namespace spec
MONGOCXX_INLINE_NAMESPACE_END
}  // namespace mongocxx

#include <mongocxx/config/private/postlude.hh>


No one can conceive the variety of feelings which bore me onwards, like a hurricane, in the first enthusiasm of success. Life and death appeared to me ideal bounds, which I should first break through, and pour a torrent of light into our dark world. A new species would bless me as its creator and source.
Within a century or even a few decades, genetic engineering and other forms of biological engineering might enable us to make far-reaching alterations not only to our physiology, immune system, but also to our intellectual and emotional capacities.
Yuval Harari, Homo Deus, 2016.
Mary Shelley's Future Shocks, devised in collaboration with BAC at a Scratch night in March, 2018, brings together the Romantic, epic words of Frankenstein with Yuval Harari's vision of the future presented in his best-seller Homo Deus: a world of artificial sentience created by Big Data, driven by a quest for bio-technical immortality. Celebrating the 200th anniversary of Frankenstein's publication in 1818- the world's first sci-fi novel – the piece bends time between the revolutionary era of Mary Shelley's teenage-hood as the creature forms in her mind and a future date decades from now, where biological 'upgrading' and multiple virtual selves are the everyday. Accompanying the projected illustrations of past and future Mary Shelley by illustrator Julia de Graaf are cinematic interludes from sci-fi, horror and surrealist films of the 1920s, 30s and 40s including Metropolis and films by Maya Deren and Jean Cocteau. In front of the screen, a harp player, string player, percussionist and vocalist augment the dream-like journey with a live score with vocal sound effects.


What Do All of My Favorite Authors Have in Common?
You know? It's funny. When it comes to my personal reading, I enjoy a variety of genres. However, what I look for most is an author who likes to add some trivia to their work.
Because of my love of trivia, it is not unusual to see me reading one of Uncle John's Bathroom Readers before dozing off to sleep.


Studying in New Zealand will give you more than an internationally recognised qualification.
You'll broaden your horizons in a western-style culture, meet new people from around the world, and see and do amazing things.
Find out more about migrating to New Zealand from Malaysia and what you need to do to get a visa to join us.
Students from around the world are welcomed at every level of New Zealand's world-class educational system. Nearly 2,000 of them, like you, come from Malaysia.
New Zealand has a wide range of educational options to choose - great secondary schools, world-ranked universities and respected technical and language institutes.
Students here are encouraged to be flexible, creative, questioning, and to be independent self-starters when it comes to finding answers. It's great preparation for further education or for the real world of employment in New Zealand, back home in Malaysia or even further afield.
"It's really peaceful when you want to study, and if you want to go have fun and party you can do that as well. It's kind of a balance."
We have excellent schools and tertiary education providers throughout the country.
Along with high academic standards, New Zealand offers students from Malaysia something more - the chance to enjoy and explore a unique culture and some of the world's most spectacular scenery.
All eight of our Universities are in the 2018 QS World Top 500 .
You'll need a student visa if the course you're considering is for longer than three months.
Various conditions apply - mainly, you'll need the offer of a place at an approved educational institution.
A student visa may let you work for up to 20 hours a week during term time, and full time in the breaks.
If your course is shorter than 3 months, you just need a visitor visa.
Once you gain a New Zealand qualification, there is a pathway that can let graduates from Malaysia get work experience or even a long-term job here.
There are some good job opportunities in New Zealand, particularly in certain fields like IT. The job market is also strong in certain parts of the country. For example workers with construction-based skills are needed in Christchurch to help with the rebuild after the earthquakes.
Your chances of getting work will be much better if your skills are among those we're short of. Check out the Government's skill shortages lists.
Once you've found a position, you may be able to apply for a work visa or possibly even one that leads to residence.
New Zealand is a well developed, English speaking country with western ways and unique Maori/Pacific Island influences.
While we have fewer people overall than Malaysia, our cities are only a little smaller than yours - Auckland's population is about 1.4 million (comparable to KL), and Wellington's is about 400,000. And while you live in a tropical country, we're much further from the equator and so temperatures are easier to live with.
As a matter of interest, people of Asian origin account for 10% of New Zealand's population. They're predicted to be the fastest growing group in the years till 2026.
We're a country that welcomes diversity. The two main communities, European and Maori, work and mix together closely, and women have important roles right through society. Corruption is almost non-existent, and while obviously we have crime, people generally feel safe to come and go as they like.
We're also a very outdoors kind of country. Who wouldn't be, when we have so many great beaches, lakes, forests and mountains on our doorstep. So we make sure we keep the sort of balance between work and living that lets us enjoy life away from our work and study.
While Malaysia is a beautiful country itself, New Zealand offers different and more diverse scenery. Along with our share of great beaches, look forward to dramatic snow-capped mountains (with great skiing!), great lakes, fjords and cool native forests.
With a much smaller population in a country twice the area of peninsular West Malaysia, there is less pressure on the environment which makes it easier to keep things clean and green.
Compared to your tropical country, we enjoy a temperate climate that makes everyday living and getting around easy, all year. We have four distinct seasons a year, and enjoy generally warm, dry summers and cooler, wet winters.
If you have family, you'll have lots to think about before making a move. But when it comes to New Zealand, you can be confident there'll be something for everyone.
New Zealand offers an educational system that is first class right from pre-school to postgraduate levels.
Our healthcare is just as well developed. There are family doctors ('general practitioners') in practically every town and suburb (Universities usually have their own Student Health services). There are also modern, well equipped hospitals in every city around the country.
Accident and emergency treatment at hospitals is free, and most care for injuries from accidents is covered under New Zealand's unique Accident Compensation scheme.


Tastings of tasty eel-based recipes will be available at the gastronomic stand organized at Palazzo Bellini, closed to the Trepponti bridge; possibility of little trips around the Historic Centre of Comacchio on board of typical lagoon craft.
At local restaurants, it will be also possible to try some local dishes, mostly eel-based. In the city centre, an expo route will be organized: there, it will be possible to find local and craft products, farm products, and artworks, as well as markets and a special area for children.


text:
Chris Steenkamp: chris@whkla.com
+264 61 331 080 +264 (0)81124 0649
64 Lazarett Street, Windhoek Namibia
Auction Averages
Auction Pens
C&J Estate Agents
Blou Willem Koffie Winkel
TRANSIT INSURANCE FOR YOUR LIVESTOCK
Western National Livestock Insurance Policy
As leaders in the livestock industry, the team of WLA is introducing an established service of TRANSIT INSURANCE to meet yet another need of farmers in the country. The transit insurance will cover the transit of livestock to the abattoir for slaughtering. Farmers can now rest assured that their livestock can be insured at a low premium of 0.5% of the freight value of the particular freight of stock. Claims are payable by WLA to the Insured on settlement of the account of the slaughtered animal(s).
Livestock can now be insured for:
Loss of or damage to an insured animal during transit to the abattoir and the slaughter of an animal at the abattoir cause by:
Animals that escape during the uploading process at the abattoir.
Damage to any animal as a result of an accident during the transit to the abattoir
Loss (Death) of an animal as a result of an accident during the transit to the abattoir is subject to a deductible (excess) of 20% of the average gross value of the consignment animals.
Loss (Death) of an animal on arrival at the abattoir is subject to a deductible (excess) of 20% of the average gross value of the sonsignment animals.
Animals that are humanely put down as a result of an accident whilst in transit and before slaughtering
Loss or damage as a result of theft of the animal(s) from the trunk or trailer whilst in transit to the abattoir
Loss of a carcass at the abattoir which has been entirely rejected as a result of bruising (Code55) is subject to a deductible (excess) of 20% of the average gross value of the consignment animals.
Loss of a carcass at the abattoir which has beenentirely rejected as a result of illness or conditions of ilness such as those diagnosed during anti- or post-mortem examinations at the abattoir and according to the Large Stock and the Small Stock Post and Ante Mortem Examination abd Compensation Payment schedules.
Download the full Insurance Policy in PDF format here.
Download Insurance Policy
Download the Application Form in PDF format here.
Livestock Transit Insurance Application Form
Livestock Transit Insurance Policy
Windhoek Livestock Auctioneers. All rights reserved. © 2018 Webdesign by Lund Media

redpajama_set_name: RedPajamaCommonCrawl


This crustose lichen grows on the vertical surfaces of exposed siliceous boulders, usually in windy sites in the mountains. It is always found growing on the surface of the leafy liverwort Gymnomitrion crenulatum which forms tight cushions that adhere like glue to the rock surface. T. thiospora has a small, scaly (squamulose) thallus comprising aggregations of rounded granules which are yellowy-green or yellow-tan in colour. The unfrosted discs are weakly convex. Very distinctive; western Ireland mainly.
The thallus is scaly, the scales rolled into yellowy granules, which causes them to stand out against the background.
Simms, M. J., (2016). Toninia thiopsora (Nyl.) H.Olivier. [In] LichenIreland.


Welcome to Digital Hit Entertainment's coverage of the 82nd Annual Academy Awards®.
The 82nd Oscars® were produced by Adam Shankman and Bill Mechanic and co-hosted by Alec Baldwin and Steve Martin. The nominations were announced on Tuesday, February 2, 2010 while the ceremony took place on Sunday, March 7, 2010, at the Kodak Theatre at Hollywood & Highland Center®. Check out our live results and commentary.
Stick with DigitalHit.com for your Academy Awards coverage.


text:
Tigranes da Arménia "o Grande" (, AOr: Tigran Mets, AOc: Dikran Medz; ) (reinou de  até ) (também chamado de Tigranes II e as vezes de Tigranes I) foi um rei da Armênia que sob o seu controle, o país se tornou por um curto tempo, o Estado mais poderoso do leste romano. Tigranes nasceu por volta de  e foi filho ou sobrinho de Artavasdes I ou Tigranes I. Tigranes, o Grande representou a Dinastia artaxíada. Casou com Cleópatra, filha de Mitrídates VI do Ponto.

Ele se envolveu em muitas batalhas durante o seu reinado. Lutou batalhas contra os partas, selêucidas e a romanos.

Reis artáxidas da Armênia
Armênios do século I a.C.

redpajama_set_name: RedPajamaWikipedia


Power Solutions International Inc. is the world's largest supplier of alternative fuel engines. Whatever fuel you fancy — natural gas, propane, biofuels — Power Solutions has an engine for it.
The Wood Dale-based company manufacturers its own engines and customizes others to run on alternative and diesel fuel. It supplies some of the biggest equipment makers in the world, including Caterpillar and General Electric, as well as Zamboni, that ubiquitous ice rink cleaner. Today, environmental regulations coupled with the low cost of natural gas are putting Power Solutions in a good spot, said Eric Cohen, the company's chief operating officer. Since 2012, Power Solutions' workforce has doubled to 450 employees, and the company recently acquired a plant in Dalian, China. Last year, Power Solutions' revenue hit an all-time high of $237 million. Mr. Cohen said it aims to reach $1 billion in revenue by 2018.


Our client issued tax invoices in respect of its work. Unfortunately, the builder soon entered into Administration so our client issued a subcontractors' charge pursuant to the SCA for the unpaid tax invoices to the developer. Several other subcontractors also lodged charges. The developer paid the funds into Court and the builder proceeded to issue a notice under the SCA certifying the full amount claimed by our client as owing.
Several of the parties commenced proceedings to secure their charges within the one-month time limit. Our client did not. These parties then successfully applied to have the proceedings combined and the funds paid out of Court. The Court retained an amount for our client's claim.
Our client proceeded to obtain legal advice that his subcontractors' charge had expired because he had not commenced proceedings within one month after the charge had been served.
We were subsequently engaged by our client to recover the funds paid into Court.
We were required to consider whether our client's failure to commence proceedings within one month after service of the charge had caused the charge to become invalid.
Our client was fortunate in that the period the builder was in Administration stopped the one-month period from running. This period restarted once the builder entered into a deed of company arrangement.
where the one-month period our client had to commence proceedings had not expired, our client was entitled to "piggy-back" onto those charges by joining the proceedings commenced by the other subcontractors.
However, our client was not able to simply commence fresh proceedings and apply to have them joined. It needed to identify which proceedings had been commenced within the one-month period and seek to be joined to them as a Plaintiff. Fortunately, those proceedings were the proceedings in which the developer had paid money into Court.
Rostron Carlyle Rojas Lawyer, Madison Lodder, appeared and successfully obtained orders for payment of our client's charge.
The above illustrates the importance of engaging lawyers who understand the complexities of construction law and the operation of the SCA.
The RCR Construction team are able to assist in providing advice and strategies for recovery of claims made pursuant to the SCA. Contact our Construction team, please call us on (07) 3009 8444 or email us at construction@rcrlaw.com.au.


The kimono trend is having a major moment. Add an instant cool and girly factor to your outfit with this mauve floral lace insert bell-sleeve Longline Shrug. Splattered with lovely floral print, it's a must-have.
Work It - Wear it over a bodycon dress or jeans and a crop top.


text:
Aaron Craft
2017 NBA G League Expansion Draft Results
August 23rd, 2017 at 4:08pm CST by Luke Adams
The NBA G League conducted its expansion draft today, allowing the league's four new franchises to add the returning rights to 11 players apiece. The league's previously-existing 22 teams had been permitted to retain the rights to nine players each, leaving the rest of their players unprotected and free to be drafted, though no team can lose more than two players. Adam Johnson recently outlined the full details of the expansion draft process in a piece for 2 Ways & 10 Days.
The G League's four new teams this year are affiliates for the Hawks (Erie BayHawks), Grizzlies (Memphis Hustle), Bucks (Wisconsin Herd), and Clippers (Agua Caliente Clippers of Ontario). The Erie BayHawks have been in the G League for years but are technically an expansion team since the old iteration of the BayHawks was purchased by the Magic and moved to Lakeland, Florida — the Lakeland Magic will retain returning rights for former BayHawks players.
The players added today by the G League's four expansion teams won't necessarily play for them this season — in fact, it's not all that common for expansion draftees to suit up for their new clubs. Many of those players will try to catch on with an NBA team or will end up playing overseas, if they're not already on an NBA or international roster. Still, the expansion draft gives the G League's new teams some assets as they start to build their rosters for the coming season.
Listed below are the results of today's expansion draft, per the G League's official announcement. The player's former G League team is noted in parentheses, and picks are ordered by round. The teams will hold their players' rights for the next two seasons:
Erie BayHawks (Hawks)
DeAndre Daniels (Raptors 905)
Sean Kilpatrick (Delaware 87ers)*
Ronald Roberts (Reno Bighorns)
Terran Petteway (Maine Red Claws)
Casey Prather (Windy City Bulls)
Jordan Crawford (Grand Rapids Drive)*
Jordan Sibert (Iowa Energy)
Beau Beech (Long Island Nets)
Raphiael Putney (Rio Grande Valley Vipers)
Luke Harangody (Lakeland Magic)
Will Bynum (Windy City Bulls)
Memphis Hustle (Grizzlies)
Marquis Teague (Fort Wayne Mad Ants)
Okaro White (Sioux Falls Skyforce)*
D.J. Stephens (Iowa Energy)
Omari Johnson (Fort Wayne Mad Ants)
Jamaal Franklin (Long Island Nets)
Adonis Thomas (Grand Rapids Drive)
Manny Harris (Texas Legends)
Mark Tyndale (Reno Bighorns)
Jordon Crawford (Canton Charge)
Jimmer Fredette (Westchester Knicks)
Terrence Drisdom (Santa Cruz Warriors)
Wisconsin Herd (Bucks)
Vince Hunter (Sioux Falls Skyforce)
Gracin Bakumanya (Northern Arizona Suns)
Perry Ellis (Greensboro Swarm)
Corey Walden (Maine Red Claws)
Josh Davis (Greensboro Swarm)
Michael Dunigan (Canton Charge)
Jarvis Summers (Rio Grande Valley Vipers)
James Siakam (Raptors 905)
Kyle Casey (Northern Arizona Suns)
Cady Lalanne (Austin Spurs)
Tyler Harvey (Lakeland Magic)
Agua Caliente Clippers of Ontario (Clippers)
Andre Dawkins (Texas Legends)
Bryce Cotton (Oklahoma City Blue)
Corey Hawkins (Delaware 87ers)
Will Cummings (Delaware 87ers)
J.J. O'Brien (Salt Lake City Stars)
Jamil Wilson (South Bay Lakers)
Keith Steffeck (Santa Cruz Warriors)
Julian Jacobs (South Bay Lakers)
Aaron Craft (Salt Lake City Stars)
Thanasis Antetokounmpo (Westchester Knicks)
Youssou Ndoye (Austin Spurs)
Players marked with an asterisk (*) are currently on an NBA roster. If they remain under contract and are assigned to the G League, they would join their current NBA team's affiliate.
Adonis Thomas
Andre Dawkins
Beau Beech
Bryce Cotton
Cady Lalanne
Casey Prather
Corey Walden
D.J. Stephens
DeAndre Daniels
Gracin Bakumanya
J.J. O'Brien
Jamaal Franklin
James Siakam
Jarvis Summers
Jimmer Fredette
Jordan Crawford
Jordan Sibert
Jordon Crawford
Josh Davis (San Diego State)
Julian Jacobs
Keith Steffeck
Kyle Casey
Luke Harangody
Manny Harris
Mark Tyndale
Marquis Teague
Michael Dunigan
Omari Johnson
Raphiael Putney
Ronald Roberts Jr.
Sean Kilpatrick
Terran Petteway
Terrence Drisdom
Thanasis Antetokounmpo
Will Cummings
Youssou Ndoye
Western Notes: Conley, Bogdanovic, Jazz Arena
June 14th, 2016 at 8:01pm CST by Arthur Hill
There is growing concern in the Grizzlies' front office that point guard Mike Conley might leave the team in free agency this summer, posts Ian Begley on ESPN Now. The 28-year-old will be the top point guard on the market after spending nine years in Memphis. Begley says Grizzlies part-owner Justin Timberlake will appear in a video presentation trying to convince Conley to remain with the team. Begley presents the item as possible good news for the Knicks, but it's equally positive for all the teams planning to pursue Conley, and very negative for Memphis, which is hoping to keep the core of its perennial playoff team together. The Grizzlies still have the advantage of being able to offer Conley a five-year contract worth about $124MM, while other teams are limited to four years in the neighborhood of $92MM.
There's more news from the Western Conference:
The Suns will negotiate with 2014 first-round pick Bogdan Bogdanovic now that his Turkish League season is over, according to Paul Coro of The Arizona Republic. This is the last season that Bogdanovic would be required to sign a rookie contract that would give him a salary of about $5.7MM over four years. If he waits until next offseason, Bogdanovic is free to negotiate any amount, starting with his draft year's rookie salary scale.
A request for $22.7MM in public funding for renovations to Utah's Vivant Arena was approved today by the Redevelopment Agency of Salt Lake City, writes Jasen Lee of The Deseret News. The money, which will be awarded though tax increment financing over the next 25 years, makes up 18% of the total cost of the proposed $125MM project. It will include safety and security improvements, heating and air conditioning upgrades, a new solar panel system and plaza, concession, seating and premium suite improvements.
The Mavericks are planning a free agent camp June 22nd with Arnett Moultrie, Bobby Brown, Dominic McGuire and Nick Minnerath among the players invited, tweets Alex Kennedy of Basketball Insiders. Thanasis Antetokounmpo, who played two games for the Knicks this season, also received an invitation but has not confirmed that he will attend the camp (Twitter link).
The Spurs will hold a free agent camp Wednesday, Kennedy tweets, with Chris Copeland, Adonis Thomas, Victor Rudd, Scott Suggs, J.J. O'Brien and Darius Adams among those expected to attend.
The Timberwolves have had workouts for several veteran free agents, including Jimmer Fredette, Phil Pressey, Marquis Teague, Ryan Boatright, Mike James, Ra'shad James, Mark Lyons and Aaron Craft, tweets international journalist David Pick.
Arnett Moultrie
Chris Copeland
Darius Adams
Dominic McGuire
Mark Lyons
Mike Conley
Nick Minnerath
Phil Pressey
Ryan Boatright
Victor Rudd
And-Ones: Sidney, D-League, Turner
May 12th, 2015 at 10:32pm CST by Eddie Scarito
The top performing players during the 2015 NBA D-League Elite mini-camp were Aaron Craft, Adonis Thomas, Shawn Jones, and Casey Prather, Adam Johnson of D-League Digest tweets. The NBA D-League's camp offers standouts from the past season another chance to perform in front of NBA team personnel in advance of Summer Leagues and 2015 training camps, Brian Kotloff of NBA.com writes. "It's really a great thing for our league to showcase the players," Elite Mini Camp director Bob MacKinnon, a five-year NBA D-League coaching veteran, said. "Every NBA team will be represented with scouts in these two days. We changed the schedule to accommodate what NBA scouts have told us they want to see."
Here's more from around the league:
Eight NBA teams are attending a workout for former Mississippi State center Renardo Sidney tonight in Chicago, Marc J. Spears of Yahoo! Sports reports (Twitter link). The big man is a free agent and went undrafted back in 2012.
The NBA draft combine allows teams to examine more than just the players' on court abilities, and in some cases these secondary observations can mean the difference between a player getting drafted or needing to scramble to snag a training camp invite, A. Sherrod Blakely of CSNNE.com writes. "The interviews are a big part of this week," said a Western Conference official. "For teams, a lot of times it's the first chance they get to sit down with players and find out the answers to some questions that might mean the difference between that kid staying on their board or taken off entirely."
Texas big man Myles Turner has a chance to contribute immediately and possibly become a building block for a future contending team, Michael Scotto of Sheridan Hoops writes. Turner is looking to make a splash in the league, saying, "Definitely a long-term goal is to get Rookie of the Year and get into the NBA All-Star Weekend. As far as short-term goals, I'd like to be able to have a great role within the team I'm drafted by to be able to go out there and get quality minutes instead of riding the bench the whole entire rookie season." The 19-year-old is the No. 10 overall prospect according to Ford, while Jonathan Givony of DraftExpress slots him at No. 11. You can view Hoops Rumors' expanded profile of Turner here.
2015 NBA Draft
Myles Turner
Renardo Sidney
Shawn Jones
California Notes: Kobe, Green, Craft, Rivers
January 18th, 2015 at 3:22pm CST by Charlie Adams
Although Kobe Bryant contends he'll likely play through his current contract, which expires after the 2015/16 season, he admits that he's at least considered hanging it up at the end of this year, relays Bill Plaschke of the Los Angeles Times. "I'd be lying if I said that it hasn't crossed my mind," Bryant said of retiring. "Right now I doubt it … but anything's possible… You have to find new challenges, not playing for a championship, it's pretty tough." The Lakers sit near the bottom of the Western Conference at 12-29, but Bryant says the team would never consider tanking, going as far as to call the practice "sacrilegious," notes Plaschke.
There's more form the California-based teams:
Lessons that the Warriors' Draymond Green learned at Michigan State are going to lead to a huge contract this summer, suggests Diamond Leung of The Bay Area News Group. A second-round pick three years ago, Green has blossomed into one of Golden State's leaders and will be a restricted free agent this summer. "The guy really is a coach's dream," said Warriors assistant Alvin Gentry. "You can't place a value on that. Use every cliché you can. His teams always win. The squad you put him on in a scrimmage, his team is going to win."
Aaron Craft has generated a positive buzz as a result of his performance at the D-League showcase, observes Scott Howard-Cooper of NBA.com, who adds that the 23-year-old guard out of Ohio State is on NBA teams' radars (Twitter link). Craft was cut from the Warriors out of training camp and currently suits up for the Santa Cruz Warriors, Golden State's D-League affiliate.
The Clippers' Doc Rivers and Austin Rivers are trying to downplay their father/son and coach/player relationship, reports Ben Bolch of The Los Angeles Times. "I'm over it," Austin Rivers said. "[Friday] night was about the son thing and I'm done with that. Now it's basketball for me." Los Angeles acquired Rivers from the Celtics Thursday in a three-team deal involving the Suns. The younger Rivers "jumped at the opportunity" to join L.A., as he tells A. Sherrod Blakely of CSNNE.
Arthur Hill contributed to this post.
Western Notes: Craft, Gasol, Ledo
December 18th, 2014 at 10:09pm CST by Eddie Scarito
NBA executives are growing increasingly intrigued with guard Aaron Craft, who is currently playing in the D-League for the Santa Cruz Warriors, Golden State's affiliate, Sam Amico of FOX Sports Ohio reports (Twitter link). Craft was in training camp with the Warriors this season, and was considering a contract offer from Partizan Belgrade of the Serbian League back in November, but he chose to remain with Santa Cruz rather than head overseas.
Here's more from the Western Conference:
The Spurs seem poised to chase Marc Gasol in free agency this coming summer, but there's little call for them to go after a replacement for Tim Duncan when Duncan continues to demonstrate that he can still play at a high level, opines Buck Harvey of the San Antonio Express-News.
The Mavericks have assigned Ricky Ledo to the Texas Legends, their D-League affiliate, Earl K. Sneed of Mavs.com reports (Twitter link). This is Ledo's fifth excursion of the season to the D-League.
Mavs owner Mark Cuban believes the most difficult choice a team owner has to make is selecting a head coach, Eddie Sefko of The Dallas Morning News writes. Cuban said there are different kinds of coaches for different kinds of jobs, including jobs that may inherently not be long-term fits, Sefko adds. "What do you expect [from coaches], and are they living up to it?" Cuban said. "Is it wins and losses or player development? How many coaches do you know that they knew the team was going to be down [before taking the job]? We've all heard about coaches who were brought in and were there to take the beating until they turn things around. You hear about that all the time. I haven't been in that position, fortunately. And it takes one type of coach rather than another."
Chuck Myron contributed to this post.
Ricky Ledo
Western Notes: Bryant, Garrett, Craft, Smith
November 8th, 2014 at 8:42pm CST by Chris Crouse
Kobe Bryant needs to take a step back and allow some of his teammates to take charge of the Lakers, opines Mike Bresnahan of the Los Angeles Times. Coach Byron Scott agrees. "I've talked to a couple individuals about just being a little bit more assertive, not relying on Kobe as much," Scott said. "You guys can ask Kobe this. I think he wants to get those guys to step up. He really does. Take shots when they have them. Not defer to him as much." Earlier this week in a loss to the Suns, Bryant took 37 shots, while the rest of the team's starters combined to take only 35.
Diante Garrett will be returning to the Iowa Energy, who are the D-League affiliates of the Grizzlies, the team announced. The Blazers recently waived the Iowa State product after spending just a month on their roster.
Aaron Craft is mulling a contract offer from Partizan Belgrade of the Serbian League, Orazio Cauchi of Sportando reports. Craft spent training camp with the Warriors and was set to play for Golden State's D-League affiliate this season. Though the amount of Partizan Belgrade's offer to Craft has not been reported, it's likely for more than the guard would have earned playing in Santa Cruz this season, though that is just my speculation.
Ish Smith is excited to be the newest member of the Thunder because of his relationship with his new teammates, writes Anthony Slater of the Oklahoman. "I'm really good friends with a lot of guys, played against them. Russ (Russell Westbrook), (Kevin Durant), Lance (Thomas), all in the '06 class, so I know a lot of them," Smith said.
Canada is producing basketball prospects at unheard of rates, writes Dave Skretta of the Associated Press. Andrew Wiggins and Anthony Bennett of the Wolves are the past two No. 1 overall NBA draft picks and are each of Canadian descent. Many, including Bennett, have attributed their interest in basketball to watching Vince Carter when he was on the Raptors. "That's when we seen him doing all these types of dunks," Bennett said of watching Carter. "We just had a love for his game."
Eddie Scarito contributed to this post.
Diante Garrett
And-Ones: Brazil, Shorter Games, Hawks, Nets
October 27th, 2014 at 1:52pm CST by Chuck Myron
The NBA has struck a deal to partner with Brazil's Liga Nacional de Basquete, the top domestic league in that country, Grantland's Zach Lowe reports. The arrangement will likely give the NBA an ownership stake in the league and will allow for the exchange of ideas on marketing, player development and other best practices, according to Lowe. Many NBA league office types would like to see the pro game played with one universal set of rules around the globe, a sentiment that some others around international basketball share, Lowe notes, so the Brazilian deal could be a step in that direction. There's more from Lowe amid our look at the latest around the league:
There's "nearly unanimous" opposition to the idea of reducing the length of games to 44 minutes, as Lowe writes in the same piece, laying out a handful of reasons why many around the league are against the idea that the NBA experimented with earlier this month. Still, Lowe believes there's a decent chance the idea resurfaces at some point.
Sources tell Daniel Kaplan of SportsBusiness Journal that they expect the Hawks to sell for at least $750MM and perhaps close to $1 billion. Presumably, those figures pertain to 100% of the franchise, and it's still uncertain just how much of the Hawks will end up on the block.
Evercore Partners, with Bruce Ratner at the controls, is once more shopping its 20% share of the Nets after tabling that pursuit earlier, Kaplan adds.
Warriors camp invitee Aaron Craft will play for the team's D-League affiliate, his agent tells Bob Baptist of The Columbus Dispatch (Twitter link). That signals that Golden State made him one of the four preseason cuts it can reserve for its affiliate, since Craft would otherwise have to go through the D-League draft.
Kim English, whom the Bulls waived earlier this month, has a deal with SLUC Nancy, a French team, sources tell Sportando's Emiliano Carchia.
Kim English
Warriors Waive Five Players
October 25th, 2014 at 8:05am CST by Eddie Scarito
The Warriors have waived Aaron Craft, Jason Kapono, Sean Kilpatrick, James Michael McAdoo, and Mitchell Watt, the team announced in a press release. These moves will reduce Golden State's preseason roster count to 15, which is the regular season maximum. None of these moves come as a surprise as all were longshots to make the regular season roster. All of the players except for Kapono had partial guarantees for $35K. Kapono's deal was non-guaranteed, so the Warriors aren't on the hook for any money for him.
Craft averaged 8.9 PPG and 4.7 APG during his four seasons at Ohio State. He put up 7.4 points in 22.0 minutes per contest in July during Las Vegas summer league play for the Warriors after going undrafted in June. The 22-year-old also joined the Sixers for the Orlando summer league, though he didn't see nearly as much playing time. Craft appeared in four preseason games, averaging 3.0 points, 2.5 rebounds, 1.5 assists and 1.00 steal in 14.7 minutes per contest.
The veteran Kapono appeared in five preseason games, averaging 3.2 and 1.6 rebounds in 8.7 minutes per game. The 6'8″, 33 year-old swingman last played in the NBA during the 2011/12 season when he appeared in 27 games for the Lakers. Kapono's career numbers over nine seasons are 6.7 PPG, 1.7 RPG, and 0.8 APG. His career slash line is .442/.434/.835. He had officially announced his retirement back in May of this year, but decided to give making the Warriors a shot.
The undrafted Kilpatrick signed with the Warriors on October 20th but did not see any action in the preseason. McAdoo appeared in five preseason games, averaging 5.6 PPG, 3.6 RPG and 1.2 SPG in 13.0 minutes per contest. Watt appeared in two preseason games, averaging 3.5 points, 2.0 rebounds, 1.5 assists and a team-leading 1.5 blocks while logging 9.5 minutes per game.
James McAdoo
Jason Kapono
Mitchell Watt
Western Notes: Faried, Warriors, Andersen
September 11th, 2014 at 8:16pm CST by Eddie Scarito
Kenneth Faried's stellar play with Team USA is going to raise his asking price during his upcoming extension talks with the Nuggets, Sean Deveney of The Sporting News writes. A few months ago a GM told Deveney that Faried was going to be paid in the Paul Millsap ($9.5MM) or Taj Gibson ($8MM) range, but now he'll most likely command a salary more comparable to Al Jefferson's ($13.7MM), the GM opines.
Here's more from the west:
Such a deal for Faried would carry a risk for Denver, according to what one Western Conference assistant coach told Deveney. The assistant said, "I guess you don't know what kind of production he would give you over a long period of time. What happens if they get Danilo Gallinari back and healthy? Now they have Arron Afflalo back. Ty Lawson and JaVale McGee were not healthy last year. How much will having those guys affect his numbers?"
The Warriors gave partial guarantees of $35K apiece to Aaron Craft, James Michael McAdoo, Mitchell Watt and Justin Holiday, all of whom are on one-year deals for the minimum salary, as Pincus reports in a pair of tweets and on the Basketball Insiders Warriors salary page.
David Andersen has signed with ASVEL Villeurbanne of the French League, the team announced via Twitter (translation by Enea Trapani of Sportando). Earlier this summer he was eying a possible return to the NBA. Andersen played two seasons in the league, and made his last appearance in the association during the 2010/11 campaign with the Pelicans. His NBA career averages are 4.9 PPG and 2.8 RPG. His career slash line is .440/.347/.674.
Justin Holiday
Warriors Sign Aaron Craft
September 2nd, 2014 at 4:45pm CST by Chuck Myron
SEPTEMBER 2ND: The deal is official, the team announced via press release.
AUGUST 6TH: The Warriors and former Ohio State point guard Aaron Craft have agreed to terms on a one-year deal with a partial guarantee, agent Lance Young tells Diamond Leung of the Bay Area News Group. It's almost assuredly a minimum-salary arrangement, since Golden State is limited to paying no more than that.
The news comes not long after a report that Warriors reserve guard Nemanja Nedovic suffered a stress fracture in his right foot, as Leung points out, suggesting that Craft is an insurance policy in case Nedovic isn't healed in time for the season. Still, the partial guarantee represents an investment in Craft, and it at least ensures he won't walk away empty-handed should he fail to make the opening-night roster.
Craft earned raves from Warriors coach Steve Kerr for his play in college, as Leung notes (on Twitter), in spite of never having averaged more than 10.0 points per game over the course of his four seasons with the Buckeyes. He put up 7.4 points in 22.0 minutes per contest last month during Las Vegas summer league play for the Warriors after going undrafted in June. The 22-year-old also joined the Sixers for the Orlando summer league, though he didn't see nearly as much playing time.
Atlantic Notes: Knicks, Rose, Wooten, Anderson


Wear loose, comfortable clothing for the procedure.
Plan to take it easy for 24 hours after the surgery. We do not expect you to have much discomfort but want to allow the area to heal without being disturbed for this period.
Moderate exertion is not recommended.
Do not take any aspirin products for 5 days before the procedure. Anti-inflammatories such as Advil, Aleve, etc., should be discontinued 24 hours prior to surgery unless instructed otherwise.
If you were given prescriptions ahead of time, have these filled prior to your appointment.
You will probably be given a long-acting anesthetic for the procedure that may last 6 or more hours. You should eat a nutritious, moderate meal ahead of time but not a heavy, full meal. You will be asked to be on a liquid diet for 24 hours after the procedure and soft foods for a few days after that.
A biopsy may be performed if there is any bone or tissue that appears questionable. This tissue will be removed and sent to a pathology lab to be tested and the lab costs will be the patient's responsibility.
Please follow this link to open a print friendly version of these instructions.


The success of a company or business and its culture is a direct reflection of the CEO/Owner – Every top athlete in the world has a coach, and a wise executive does too. It has been statistically shown that executives with a coach consistently outperform those that don't have one.
Discover what has been holding you back from achieving what you really desire with your company so you can finally get the results you want. Most CEOs who try to figure out their challenges on their own miss the hidden but incredibly important issues that are truly impacting their company, their team and their bottom line. When you work with us, we get you in the "know" and work with you to adapt your own leadership style to get the most from your team and resources.
Get you crystal clear and powerfully in action on what you want and the necessary behaviors on how to get there. Distinct from strategic work, coaching looks at our personal ability to align the behaviors with the strategies that have been set out.
Look objectively at your thinking & decision making framework. Discover your blind spots. You exist within a framework of thinking and decision making that has gotten you everything you have – all the success and all the challenges. Einstein said if we are to solve problems on one level we must go to another level to solve them. Trying to solve our problems from our current model of thinking won't work. Together we decode your thinking process and look at how to shift perspectives and critical reasoning to create higher levels of success.
Decode your relationship to success Companies and CEOs go through important inflection points where they have the opportunity to accelerate their business to the next level. This requires an ability to identify these critical points and create a new relationship to one's identity as a leader. We will decode your relationship to success so that you don't miss those massive opportunities, plus reshape your leadership abilities and style so you can congruently lead your team into a much larger game.
Align all the parts of you that are in conflict with the results you want in your work and in your life. We'll dissolve inner conflict and struggle around: making decisions, showing up confident and powerful to your team and Board, and coach you into experiencing a level of peace and joy that you never have had around your business and personal life.
As a key executive you are expected to drive and be part of a high performing team. The CEO, Board and growth of the company rely on you being able to execute and drive the strategic choices, inspire and congeal your team and personally perform in a high performance state.
Look at how you can be influential to establish strong team dynamics.
As a leader of a team or department, you can be revered by your team and drive them towards results that seem out of the scope of likely. We work together to discover your communication patterns (verbal and non-verbal) and how enhancing those will get you a more productive, high achieving team.
Show up as a charismatic leader for your team while becoming an indispensable component for the CEO and Board.
Becoming one of the superstars of a company means you will increase job security, effectiveness and overall connection with your team, the Board and CEO.
Be able to have a stellar day every day. You have the resources to be able to achieve extraordinary things, but conditioning yourself and your mind around being in a peak leadership place as often as possible is critical to meeting daily, weekly & monthly targets. When we work together, we work on specific personal challenges that keep you from operating in a high performance state on a daily basis.
Experience a greater satisfaction and fulfillment within yourself and your work.


2.   Bighub Holidays is a young, and fast growing company, offering the entire range of travel related services to today's discerning travelers. Committed to a philosophy of continuous improvement, our highly dedicated and qualified team believes in being one step ahead of the client, and providing him today, with what he might desire tomorrow. We have worldwide tie ups with reputed & professional companies who ensure that our client's needs are taken care in a most reliable, friendly & service oriented manner. We believe in commitment towards client satisfaction and transparency in business, thus striving to achieve long-term business relationships with our clients, based on strong corporate ethics. The Company has kept itself abreast with the revolutionary trends taking place in the travel trade, and is proud to be able to provide air ticketing, hotel reservations, car rentals, sight seeings and much more through out the world with the online reservations systems. The Company brings with itself whole gamut of practical and rich experience in every facet of travel industry, which has been widely acclaimed. The Company believes in learning and improving oneself to be able to provide more efficient and professionally managed travel solutions, and in research activities relating to the development of new products and services.