text:
#include <chrono>
#include <limits>
#include <map>
#include <string>
#include <vector>

#include "mediafire_sdk/api/billing/get_products.hpp"

#include "mediafire_sdk/api/user/get_session_token.hpp"
#include "mediafire_sdk/api/user/get_action_token.hpp"

#include "mediafire_sdk/api/folder/get_content.hpp"

#include "mediafire_sdk/utils/md5_hasher.hpp"
#include "mediafire_sdk/utils/string.hpp"

#include "boost/algorithm/string/find.hpp"
#include "boost/asio.hpp"
#include "boost/asio/ssl.hpp"
#ifdef BOOST_ASIO_SEPARATE_COMPILATION
#  include "boost/asio/impl/src.hpp"  // Define once in program
#  include "boost/asio/ssl/impl/src.hpp"  // Define once in program
#endif
#include "boost/date_time/posix_time/ptime.hpp"
#include "boost/filesystem.hpp"
#include "boost/filesystem/fstream.hpp"
#include "boost/format.hpp"
#include "boost/property_tree/json_parser.hpp"

#include "mediafire_sdk/api/unit_tests/session_token_test_server.hpp"
#include "mediafire_sdk/api/unit_tests/api_ut_helpers.hpp"

#include "mediafire_sdk/api/session_maintainer.hpp"
#define BOOST_TEST_MODULE SessionMaintainer
#include "boost/test/unit_test.hpp"

namespace api = mf::api;

namespace {

const std::string address = "127.0.0.1";
const std::string port = "60259";
const std::string host = address + ":" + port;

#if ! defined(TEST_USER_1_USERNAME) || ! defined(TEST_USER_1_PASSWORD)
# error "TEST_USER defines not set."
#endif

const std::string username = TEST_USER_1_USERNAME;
const std::string password = TEST_USER_1_PASSWORD;

enum class Regenerate
{
    No,
    Yes
};

std::string TestName()
{
    return boost::unit_test::framework::current_test_case().p_name;
}

boost::filesystem::path TemplateDir()
{
    boost::filesystem::path path(__FILE__);
    return path.parent_path();
}

std::string GetTemplate(std::string template_path)
{
    using std::ios;

    boost::filesystem::path path(TemplateDir()/template_path);
    boost::filesystem::ifstream ifs;

    ifs.open(path, ios::binary | ios::in );
    if ( ifs.is_open() && ifs.good() )
    {
        std::string contents(
            (std::istreambuf_iterator<char>(ifs)),
            (std::istreambuf_iterator<char>()   ));

        if ( ifs.eof() || ifs.good() )
            return contents;
    }

    std::ostringstream ss;
    ss << "Missing template: " << path.string();
    throw std::runtime_error(ss.str());
}

std::string InvalidSignatureResponse(
        std::string action
    )
{
    boost::property_tree::wptree pt = api::ut::MakeErrorApiContent(
            action,
            "The signature you specified is invalid",
            127 );
    return api::ut::ToString(pt);
}

}  // namespace

class FailTimer
{
public:
    FailTimer(
            boost::asio::io_service * ios,
            int timeout_seconds
        ) :
        io_service_(ios),
        timer_(*ios),
        timeout_seconds_(timeout_seconds)
    {
        io_service_->post(
            std::bind( &FailTimer::Run, this ) );
    }

    void Stop()
    {
        timer_.cancel();
    }

private:
    boost::asio::io_service * io_service_;
    boost::asio::steady_timer timer_;

    int timeout_seconds_;

    void Run()
    {
        timer_.expires_from_now(std::chrono::seconds(timeout_seconds_));
        timer_.async_wait(
            boost::bind(
                &FailTimer::HandleTimeout,
                this,
                boost::asio::placeholders::error
            )
        );
    }

    void HandleTimeout(const boost::system::error_code & err)
    {
        if (!err)
        {
            io_service_->stop();

            std::ostringstream ss;
            ss << "Timeout failure.";
            BOOST_FAIL(ss.str());
        }
    }
};

template<typename T>
class PHBinder
{
public:
    explicit PHBinder(T * t) :
        class_(t)
    {
    }

    void operator()(api::ut::RequestPointer rp)
    {
        class_->AcceptRequest( std::move(rp) );
    }

private:
    T * class_;
};

template<typename T>
api::ut::PathHandler PHBind(T * t)
{
    PHBinder<T> bound(t);
    return bound;
}

class SessionTokenWallet
{
public:
    struct SessionToken
    {
        std::string token;
        std::string pkey;
        std::string ekey;
        std::string time;

        int secret_key;
    };

    bool ValidateSignature(
            api::ut::Request * request,
            Regenerate regenerate_on_success )
    {
        if ( DoValidateSignature( request, regenerate_on_success ) )
            return true;

        std::cout << "Request INVALID: " << request->http_request_path
            << std::endl;

        return false;
    }

    bool GetValidates(
            api::ut::Request * request,
            Regenerate regenerate_on_success
        )
    {
        std::string token, signature;
        {
            auto it = request->query_parts.find("session_token");
            if ( it == request->query_parts.end() )
                return false;
            token = it->second;

            it = request->query_parts.find("signature");
            if ( it == request->query_parts.end() )
                return false;
            signature = it->second;
        }

        // Can't be good if we can't find the token.
        auto token_it = tokens_.find(token);
        if ( token_it == tokens_.end() )
            return false;

        std::string::size_type sigpos = request->http_request_path.find(
            "signature=");
        if ( sigpos == std::string::npos )
            return false;
        if (sigpos > 0)
            --sigpos;

        std::ostringstream ss;
        ss << ( token_it->second.secret_key % 256 );
        ss << token_it->second.time;
        ss << request->http_request_path.substr(0, sigpos);

        if ( signature != mf::utils::HashMd5(ss.str()) )
            return false;

        if ( regenerate_on_success == Regenerate::Yes )
            GenerateNextSecretKey(token);

        return true;
    }

    bool PostValidates(
            api::ut::Request * request,
            Regenerate regenerate_on_success
        )
    {
        std::string token, signature;
        {
            auto it = request->post_parts.find("session_token");
            if ( it == request->post_parts.end() )
            {
                return false;
            }
            token = it->second;

            it = request->post_parts.find("signature");
            if ( it == request->post_parts.end() )
            {
                return false;
            }
            signature = it->second;
        }

        // Can't be good if we can't find the token.
        auto token_it = tokens_.find(token);
        if ( token_it == tokens_.end() )
        {
            return false;
        }

        std::ostringstream ss;

        // Signature is created using secret key + time + path + post
        ss << ( token_it->second.secret_key % 256 );
        ss << token_it->second.time;

        {
            std::string::size_type sigpos = request->http_request_path.find(
                "?");
            if ( sigpos == std::string::npos )
            {
                ss << request->http_request_path;
            }
            else
            {
                ss << request->http_request_path.substr(0, sigpos);
            }
            ss << "?";
        }

        {
            std::string::size_type sigpos = request->post.find(
                "signature=");
            if ( sigpos == std::string::npos )
            {
                return false;
            }
            if (sigpos > 0)
                --sigpos;
            ss << request->post.substr(0, sigpos);
        }

        if ( signature != mf::utils::HashMd5(ss.str()) )
        {
            return false;
        }

        if ( regenerate_on_success == Regenerate::Yes )
            GenerateNextSecretKey(token);

        return true;
    }

    bool DoValidateSignature(
            api::ut::Request * request,
            Regenerate regenerate_on_success )
    {
        return ( GetValidates(request, regenerate_on_success)
            || PostValidates(request, regenerate_on_success) );
    }

    void GenerateNextSecretKey(std::string token)
    {
        auto it = tokens_.find(token);
        if ( it != tokens_.end() )
        {
            uint64_t current_key = it->second.secret_key;
            uint64_t next_key = (current_key * 16807) % 2147483647;
            it->second.secret_key = static_cast<int>(next_key);
        }
    }

    SessionToken CreateValidToken()
    {
        static boost::random::random_device rng;
        SessionToken st;

        static const std::string alphanum_chars(
                "abcdefghijklmnopqrstuvwxyz"
                "0123456789"
                );
        static boost::random::uniform_int_distribution<> alphanum_dist(
            0, alphanum_chars.size() - 1);

        // token
        const uint32_t session_token_length = 144;
        st.token.reserve(session_token_length);
        for (uint32_t i = 0; i < session_token_length; ++i)
            st.token.push_back( alphanum_chars[alphanum_dist(rng)] );

        // pkey
        // This should stay the same unless the user changes the password.
        static bool pkey_generated = false;
        static std::string pkey;
        if ( ! pkey_generated )
        {
            pkey_generated = true;
            const uint32_t pkey_length = 10;
            pkey.reserve(pkey_length);
            for (uint32_t i = 0; i < pkey_length; ++i)
                pkey.push_back( alphanum_chars[alphanum_dist(rng)] );
        }
        st.pkey = pkey;

        const uint32_t ekey_length = 32;
        st.token.reserve(ekey_length);
        for (uint32_t i = 0; i < ekey_length; ++i)
            st.ekey.push_back( alphanum_chars[alphanum_dist(rng)] );

        // secret key
        static boost::random::uniform_int_distribution<> secret_key_dist(
            0, std::numeric_limits<int32_t>::max() );
        st.secret_key = secret_key_dist(rng);

        // time
        {
            boost::posix_time::ptime now(
                boost::posix_time::microsec_clock::universal_time());
            boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1));
            boost::posix_time::time_duration since_epoch = now - epoch;
            boost::posix_time::time_duration::sec_type total_seconds =
                since_epoch.total_seconds();
            boost::posix_time::time_duration::sec_type milliseconds =
                (since_epoch - boost::posix_time::seconds(total_seconds)
                    ).total_milliseconds();
            std::ostringstream ss;
            ss << total_seconds << "."
                << std::setw(4) << std::setfill('0') << milliseconds;
            st.time = ss.str();
        }

        tokens_[st.token] = st;

        return st;
    }

    void AddValidToken(
            std::string token,
            std::string pkey,
            std::string ekey,
            std::string time,
            int secret_key
        )
    {
        SessionToken td =
        {
            token,
            pkey,
            ekey,
            time,
            secret_key
        };

        tokens_[token] = std::move(td);
    }

    void InvalidateToken(std::string token)
    {
        std::cout << "Token INVALIDATED: " << token << std::endl;
        tokens_.erase(token);
    }

private:
    std::map<std::string, SessionToken> tokens_;
};
SessionTokenWallet session_token_wallet;

class SessionTokenServer
{
public:
    SessionTokenServer() :
        tokens_served_(0)
    {
    }

    void AcceptRequest(api::ut::RequestPointer request)
    {
        std::cout << "Serving token!" << std::endl;

        SessionTokenWallet::SessionToken st =
            session_token_wallet.CreateValidToken();

        ++tokens_served_;

        boost::property_tree::wptree pt =
            api::ut::MakeBaseApiContent("1.3/user/get_session_token");
        pt.put(L"response.session_token", mf::utils::bytes_to_wide(st.token) );
        pt.put(L"response.secret_key", mf::utils::bytes_to_wide(mf::utils::to_string(st.secret_key)) );
        pt.put(L"response.time", mf::utils::bytes_to_wide(st.time) );
        pt.put(L"response.pkey", mf::utils::bytes_to_wide(st.pkey) );
        pt.put(L"response.ekey", mf::utils::bytes_to_wide(st.ekey) );

        request->Respond(api::ut::ok, api::ut::ToString(pt));
    }

    int tokens_served() const {return tokens_served_;}

private:
    int tokens_served_;
};

class GetActionTokenServer
{
public:
    GetActionTokenServer()
    {
        at_response_ = GetTemplate(
            "templates/user/get_action_token_image.txt");
    }

    void AcceptRequest(api::ut::RequestPointer request)
    {
        if ( ! session_token_wallet.ValidateSignature( request.get(),
                Regenerate::Yes ) )
        {
            request->Respond(api::ut::forbidden,
                InvalidSignatureResponse("folder/get_content"));
            return;
        }

        std::string default_str;
        std::string * to_send = &default_str;

        to_send = &at_response_;

        request->Respond(api::ut::ok, *to_send);
    }

private:
    std::string at_response_;
};

class FolderGetContentServer
{
public:
    FolderGetContentServer()
    {
        files_response_ = GetTemplate(
            "templates/folder/get_content/file_1.txt");

        folders_response_ = GetTemplate(
            "templates/folder/get_content/folder_1.txt");
    }

    void AcceptRequest(api::ut::RequestPointer request)
    {
        if ( ! session_token_wallet.ValidateSignature( request.get(),
                Regenerate::Yes ) )
        {
            request->Respond(api::ut::forbidden,
                InvalidSignatureResponse("folder/get_content"));
            return;
        }

        std::string default_str;
        std::string * to_send = &default_str;

        auto it = request->query_parts.find("content_type");
        if ( it != request->query_parts.end()
            && it->second == "files" )
        {
            to_send = &files_response_;
        }
        else
        {
            to_send = &folders_response_;
        }

        request->Respond(api::ut::ok, *to_send);
    }

private:
    std::string files_response_;
    std::string folders_response_;
};

class TimeoutServer
{
public:
    TimeoutServer(
            boost::asio::io_service * io_service,
            int seconds
        ) :
        timer_(*io_service),
        seconds_(seconds)
    {
    }

    ~TimeoutServer()
    {
        timer_.cancel();
    }

    void AcceptRequest(api::ut::RequestPointer request)
    {
        // Don't respond, but keep request around

        timer_.expires_from_now( std::chrono::seconds(seconds_) );
        timer_.async_wait(
            boost::bind(
                &TimeoutServer::HandleTimeout,
                this,
                request,
                boost::asio::placeholders::error
            )
        );
    }

    void HandleTimeout(
            api::ut::RequestPointer /*request*/,
            const boost::system::error_code & err
        )
    {
        if (!err)
        {
            std::cout << "Timeout reached!  Releasing request." << std::endl;
        }
    }

private:
    boost::asio::steady_timer timer_;
    int seconds_;
};

class SessionTokenSimpleResponder
{
public:
    SessionTokenSimpleResponder(
            api::ut::HttpStatusCode status_code,
            std::string response
        ) :
        status_code_(status_code),
        response_(std::move(response))
    {
    }

    void AcceptRequest(api::ut::RequestPointer request)
    {
        request->Respond(status_code_, response_);
    }

private:
    api::ut::HttpStatusCode status_code_;
    std::string response_;
};

BOOST_AUTO_TEST_CASE(FolderGetContentFolders)
{
    boost::asio::io_service io_service;
    FailTimer ft(&io_service, 2);

    api::ut::PathHandlers handlers;

    SessionTokenServer st_responder;
    handlers["/api/1.3/user/get_session_token.php"] = PHBind(&st_responder);

    FolderGetContentServer rcc_responder;
    handlers["/api/1.2/folder/get_content.php"] = PHBind(&rcc_responder);

    api::ut::SessionTokenTestServer server(
        &io_service,
        address,
        port,
        std::move(handlers)
    );

    auto http_config = mf::http::HttpConfig::Create();
    http_config->SetWorkIoService(&io_service);
    http_config->AllowSelfSignedCertificate();

    api::SessionMaintainer stm(
        http_config,
        host
    );
    stm.SetLoginCredentials( api::credentials::Email{ username, password } );

    api::folder::get_content::Request get_content(
        "myfiles",  // folder_key
        0,  // chunk
        api::folder::get_content::ContentType::Folders  // content_type
    );

    stm.Call(
        get_content,
        [&]( const api::folder::get_content::Response & response )
        {
            ft.Stop();
            io_service.stop();

            if ( response.error_code )
            {
                std::cout << response.debug << std::endl;

                std::ostringstream ss;
                ss << "Error: " << response.error_string << std::endl;
                BOOST_FAIL(ss.str());
            }
            else
            {
                std::cout << "Success!" << std::endl;
            }
        }
    );

    std::cout << "Starting " << TestName() <<  " main loop" << std::endl;
    io_service.run();

    BOOST_CHECK_EQUAL( st_responder.tokens_served(), 1 );
}

BOOST_AUTO_TEST_CASE(FolderGetContentFiles)
{
    boost::asio::io_service io_service;
    FailTimer ft(&io_service, 2);

    api::ut::PathHandlers handlers;

    SessionTokenServer st_responder;
    handlers["/api/1.3/user/get_session_token.php"] = PHBind(&st_responder);

    FolderGetContentServer rcc_responder;
    handlers["/api/1.2/folder/get_content.php"] = PHBind(&rcc_responder);

    api::ut::SessionTokenTestServer server(
        &io_service,
        address,
        port,
        std::move(handlers)
    );

    auto http_config = mf::http::HttpConfig::Create();
    http_config->SetWorkIoService(&io_service);
    http_config->AllowSelfSignedCertificate();

    api::SessionMaintainer stm(
        http_config,
        host
    );
    stm.SetLoginCredentials( api::credentials::Email{ username, password } );

    api::folder::get_content::Request get_content(
        "myfiles",  // folder_key
        0,  // chunk
        api::folder::get_content::ContentType::Files  // content_type
    );

    stm.Call(
        get_content,
        [&](const api::folder::get_content::Response & response)
        {
            ft.Stop();
            io_service.stop();

            if (response.error_code)
            {
                std::cout << response.debug << std::endl;

                std::ostringstream ss;
                ss << "Error: " << response.error_string << std::endl;
                BOOST_FAIL(ss.str());
            }
            else
            {
                std::cout << "Success!" << std::endl;
            }
        }
    );

    std::cout << "Starting " << TestName() <<  " main loop" << std::endl;
    io_service.run();

    BOOST_CHECK_EQUAL( st_responder.tokens_served(), 1 );
}

BOOST_AUTO_TEST_CASE(RepeatedTokenVerify)
{
    boost::asio::io_service io_service;

    // No Stop needed as io_service::stop called.
    FailTimer ft(&io_service, 10);

    api::ut::PathHandlers handlers;

    SessionTokenServer st_responder;
    handlers["/api/1.3/user/get_session_token.php"] = PHBind(&st_responder);

    FolderGetContentServer rcc_responder;
    handlers["/api/1.2/folder/get_content.php"] = PHBind(&rcc_responder);

    api::ut::SessionTokenTestServer server(
        &io_service,
        address,
        port,
        std::move(handlers)
    );

    auto http_config = mf::http::HttpConfig::Create();
    http_config->SetWorkIoService(&io_service);
    http_config->AllowSelfSignedCertificate();

    api::SessionMaintainer stm(
        http_config,
        host
    );
    stm.SetLoginCredentials( api::credentials::Email{ username, password } );

    class RepeatCaller
    {
    public:
        RepeatCaller(
                api::SessionMaintainer * stm,
                int * times_to_run_countdown,
                boost::asio::io_service * io_service
            ) :
            stm_(stm),
            times_to_run_countdown_(times_to_run_countdown),
            io_service_(io_service),
            get_content_(
                "myfiles",  // folder_key
                0,  // chunk
                api::folder::get_content::ContentType::Files  // content_type
            )
        {
        }

        void operator()( const api::folder::get_content::Response & response )
        {
            if ( response.error_code )
            {
                std::cout << response.debug << std::endl;

                std::ostringstream ss;
                ss << "Error: " << response.error_string << std::endl;
                BOOST_FAIL(ss.str());
            }

            if ( ! *times_to_run_countdown_ )
            {
                io_service_->stop();
            }
            else
            {
                --*times_to_run_countdown_;
                Run();
            }
        }

        void Run()
        {
            stm_->Call( get_content_, *this );
        }
    private:
        api::SessionMaintainer * stm_;
        int * times_to_run_countdown_;
        boost::asio::io_service * io_service_;
        api::folder::get_content::Request get_content_;
    };

    int times_to_run_countdown = 100;
    RepeatCaller rc(&stm, &times_to_run_countdown, &io_service);

    rc.Run();

    std::cout << "Starting " << TestName() <<  " main loop" << std::endl;
    io_service.run();

    // The number of tokens requested should still be 1, as the session token
    // has no reason to expire.
    BOOST_CHECK_EQUAL( st_responder.tokens_served(), 1 );
}

BOOST_AUTO_TEST_CASE(RepeatedParallelTokenVerify)
{
    std::cout << "Begin:  " << TestName() << std::endl;

    boost::asio::io_service io_service;

    // No Stop needed as io_service::stop called.
    FailTimer ft(&io_service, 10);

    api::ut::PathHandlers handlers;

    SessionTokenServer st_responder;
    handlers["/api/1.3/user/get_session_token.php"] = PHBind(&st_responder);

    FolderGetContentServer rcc_responder;
    handlers["/api/1.2/folder/get_content.php"] = PHBind(&rcc_responder);

    api::ut::SessionTokenTestServer server(
        &io_service,
        address,
        port,
        std::move(handlers)
    );

    auto http_config = mf::http::HttpConfig::Create();
    http_config->SetWorkIoService(&io_service);
    http_config->AllowSelfSignedCertificate();

    api::SessionMaintainer stm(
        http_config,
        host
    );
    stm.SetLoginCredentials( api::credentials::Email{ username, password } );

    class RepeatCaller
    {
    public:
        RepeatCaller(
                api::SessionMaintainer * stm,
                int * times_to_run_countdown,
                boost::asio::io_service * io_service
            ) :
            stm_(stm),
            times_to_run_countdown_(times_to_run_countdown),
            io_service_(io_service),
            get_content_(
                "myfiles",  // folder_key
                0,  // chunk
                api::folder::get_content::ContentType::Files  // content_type
            )
        {
        }

        void operator()( const api::folder::get_content::Response & response )
        {
            if ( response.error_code )
            {
                std::cout << response.debug << std::endl;

                std::ostringstream ss;
                ss << "Error: " << response.error_string << std::endl;
                BOOST_FAIL(ss.str());
            }

            if ( ! *times_to_run_countdown_ )
                io_service_->stop();
            else
            {
                --*times_to_run_countdown_;
                Run();
            }
        }

        void Run()
        {
            stm_->Call( get_content_, *this );
        }
    private:
        api::SessionMaintainer * stm_;
        int * times_to_run_countdown_;
        boost::asio::io_service * io_service_;
        api::folder::get_content::Request get_content_;
    };

    {
        const int count = 10;
        const std::size_t parallel_instances =
            api::SessionMaintainer::max_tokens + 4;
        std::array<int, parallel_instances> counts;
        std::array<std::unique_ptr<RepeatCaller>, parallel_instances> callers;

        for ( std::size_t i = 0; i < parallel_instances; ++i )
        {
            counts[i] = count;
            RepeatCaller * rc = new RepeatCaller(&stm, &counts[i], &io_service);
            callers[i].reset(rc);
            callers[i]->Run();
        }

        std::cout << "Starting " << TestName() <<  " main loop" << std::endl;
        io_service.run();
        std::cout << "Completed " << TestName() <<  " main loop" << std::endl;
    }

    // We shouldn't go over the number of max tokens.
    BOOST_CHECK_EQUAL(
        st_responder.tokens_served(),
        api::SessionMaintainer::max_tokens );
}

BOOST_AUTO_TEST_CASE(GetActionToken)
{
    boost::asio::io_service io_service;
    FailTimer ft(&io_service, 2);

    api::ut::PathHandlers handlers;

    SessionTokenServer st_responder;
    handlers["/api/1.3/user/get_session_token.php"] = PHBind(&st_responder);

    GetActionTokenServer at_responder;
    handlers["/api/1.3/user/get_action_token.php"] = PHBind(&at_responder);

    api::ut::SessionTokenTestServer server(
        &io_service,
        address,
        port,
        std::move(handlers)
    );

    auto http_config = mf::http::HttpConfig::Create();
    http_config->SetWorkIoService(&io_service);
    http_config->AllowSelfSignedCertificate();

    api::SessionMaintainer stm(
        http_config,
        host
    );
    stm.SetLoginCredentials( api::credentials::Email{ username, password } );

    using api::user::get_action_token::Type;

    api::user::get_action_token::Request image_request(Type::Image);
    api::user::get_action_token::Request upload_request(Type::Upload);

    int callback_count = 0;
    const int callback_count_expected = 2;
    auto callback(
        [&](const api::user::get_action_token::Response & response)
        {
            ++callback_count;

            if ( callback_count == callback_count_expected )
            {
                ft.Stop();
                io_service.stop();
            }

            if (response.error_code)
            {
                std::cout << response.debug << std::endl;

                std::ostringstream ss;
                ss << "Error: " << response.error_string << std::endl;
                BOOST_FAIL(ss.str());
            }
            else
            {
                std::cout << "Success!" << std::endl;
            }
        });

    stm.Call( image_request, callback );
    stm.Call( upload_request, callback );

    std::cout << "Starting " << TestName() <<  " main loop" << std::endl;
    io_service.run();
}

BOOST_AUTO_TEST_CASE(TimeoutSeconds)
{
    boost::asio::io_service io_service;
    FailTimer ft(&io_service, 10);

    api::ut::PathHandlers handlers;

    SessionTokenServer st_responder;
    handlers["/api/1.3/user/get_session_token.php"] = PHBind(&st_responder);

    TimeoutServer rcc_responder(&io_service, 10);
    handlers["/api/1.2/folder/get_content.php"] = PHBind(&rcc_responder);

    api::ut::SessionTokenTestServer server(
        &io_service,
        address,
        port,
        std::move(handlers)
    );

    auto http_config = mf::http::HttpConfig::Create();
    http_config->SetWorkIoService(&io_service);
    http_config->AllowSelfSignedCertificate();

    api::SessionMaintainer stm(
        http_config,
        host );
    stm.SetLoginCredentials( api::credentials::Email{ username, password } );

    // Set timeout seconds to short amount to ensure timeout happens correctly.
    stm.SetTimeoutSeconds(0);

    api::folder::get_content::Request get_content(
        "myfiles",  // folder_key
        0,  // chunk
        api::folder::get_content::ContentType::Folders  // content_type
    );

    stm.Call(
        get_content,
        [&io_service, &ft, &stm](
                const api::folder::get_content::Response & response
            )
        {
            if ( response.error_code ==
                api::api_code::SessionTokenUnavailableTimeout )
            {
                std::cout << "Successful timeout" << std::endl;
            }
            else if ( response.error_code )
            {
                std::cout << response.debug << std::endl;

                std::ostringstream ss;
                ss << "Error: " << response.error_string << std::endl;
                BOOST_FAIL(ss.str());
            }
            else
            {
                BOOST_FAIL("Response succeeded where it should not have.");
            }

            std::cout << "Calling possible single thread deadlock." << std::endl;
            stm.StopTimeouts();

            // Still stop io_service to prevent assert in session manager.
            ft.Stop();
            io_service.stop();
        }
    );

    std::cout << "Starting " << TestName() <<  " main loop" << std::endl;
    io_service.run();
}

BOOST_AUTO_TEST_CASE(CleanupAssurance)
{
    using api::user::get_action_token::Type;

    boost::asio::io_service io_service;
    FailTimer ft(&io_service, 10);

    api::ut::PathHandlers handlers;

    SessionTokenServer st_responder;
    handlers["/api/1.3/user/get_session_token.php"] = PHBind(&st_responder);

    GetActionTokenServer at_responder;
    handlers["/api/1.3/user/get_action_token.php"] = PHBind(&at_responder);

    api::ut::SessionTokenTestServer server(
        &io_service,
        address,
        port,
        std::move(handlers)
    );

    auto http_config = mf::http::HttpConfig::Create();
    http_config->SetWorkIoService(&io_service);
    http_config->AllowSelfSignedCertificate();

    auto stm = std::make_shared<api::SessionMaintainer>(
        http_config,
        host );
    stm->SetLoginCredentials( api::credentials::Email{ username, password } );

    // Make a bunch of requests and make sure they all get called correctly,
    // event if the stm is reset.
    int callback_count = 0;
    const int callback_count_expected = 30;
    auto callback(
        [&stm, &ft, &callback_count, &io_service, callback_count_expected](
                const api::user::get_action_token::Response & /*response*/
            )
        {
            ++callback_count;
            if (stm)
            {
                std::cout << "Destroying SessionMaintainer." << std::endl;
                stm.reset();
                std::cout << "SessionMaintainer destroyed." << std::endl;
            }

            // Can stop if all request callbacks counted for.
            if (callback_count == callback_count_expected)
            {
                ft.Stop();
                io_service.stop();
            }
        });

    for (int i = 0; i < callback_count_expected; ++i)
    {
        stm->Call(
            api::user::get_action_token::Request(Type::Upload),
            callback
        );
    }

    std::cout << "Starting " << TestName() <<  " main loop" << std::endl;
    io_service.run();

    if (stm)
    {
        BOOST_FAIL("Test invalid as SessionManager still exists!");
    }

    BOOST_CHECK_EQUAL( callback_count, callback_count_expected );
}

/** @todo hjones: Add test to ensure session token manager doesn't spam server
 * when failures occur. */


text:
package com.expedia.echox3.basics.tools;

import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;

import com.expedia.echox3.basics.AbstractTestTools;
import com.expedia.echox3.basics.collection.simple.StringGroup;
import com.expedia.echox3.basics.configuration.ConfigurationManager;
import com.expedia.echox3.basics.monitoring.counter.IOperationContext;
import com.expedia.echox3.basics.monitoring.event.BasicEvent;
import com.expedia.echox3.basics.thread.AbstractBaseThread;
import com.expedia.echox3.basics.tools.locks.AbstractReadWriteLock;
import com.expedia.echox3.basics.tools.locks.AtomicReadWriteLock;
import com.expedia.echox3.basics.tools.locks.BasicReadWriteLock;
import com.expedia.echox3.basics.tools.locks.FastReadWriteLock;
import com.expedia.echox3.basics.tools.locks.LockCounterFamily;
import com.expedia.echox3.basics.tools.locks.PlainReadWriteLock;
import com.expedia.echox3.basics.tools.misc.BasicTools;

//import static org.junit.Assert.assertEquals;

public class RWLockTests extends AbstractTestTools
{
	private static final String[]					GLOBAL_LOCK_NAME	=
			{ RWLockTests.class.getSimpleName(), "Global" };
	private static final AbstractReadWriteLock GLOBAL_LOCK = AbstractReadWriteLock.createReadWriteLock(
					new LockCounterFamily(new StringGroup(GLOBAL_LOCK_NAME)));

	public static AbstractReadWriteLock getLock()
	{
		return GLOBAL_LOCK;
	}

	@BeforeClass
	public static void beforeClass()
	{
		// Load configuration...
		ConfigurationManager.getInstance();
	}

	@Test
	public void testHello()
	{
		logTestName();

		validateSingleLock(true , 10, 10);
		validateSingleLock(true , 10, 20);
		validateSingleLock(true , 20, 10);
		validateSingleLock(false, 10, 10);
		validateSingleLock(false, 10, 20);
		validateSingleLock(false, 20, 10);
	}
	private void validateSingleLock(boolean isWrite, long timeAsk, long timeRelease)
	{
		long			timeStart	= getStartTime();
		RWLockThread	thread		= new RWLockThread("Single", isWrite, timeStart, timeAsk, timeAsk, timeRelease);
		thread.waitUntilDone();
		thread.validate(5);
	}

	@Test
	public void testMultipleRead()
	{
		logTestName();

		long			timeStart	= getStartTime();
		RWLockThread[]	threadList	= new RWLockThread[3];
		threadList[0] = new RWLockThread("R0", false, timeStart, 20, 20, 30);
		threadList[1] = new RWLockThread("R1", false, timeStart, 20, 20, 30);
		threadList[2] = new RWLockThread("R1", false, timeStart, 20, 20, 30);

		validateThreadList(threadList, 5);
	}

	@Test
	public void testMultipleWrite()
	{
		logTestName();

		long			timeStart	= getStartTime();
		RWLockThread[]	threadList	= new RWLockThread[3];
		threadList[0] = new RWLockThread("W0", true, timeStart, 20, 20, 50);
		threadList[1] = new RWLockThread("W1", true, timeStart, 25, 50, 60);
		threadList[2] = new RWLockThread("W1", true, timeStart, 30, 60, 70);

		validateThreadList(threadList, 5);
	}

	@Test
	public void testRWR()
	{
		logTestName();

		long			timeStart	= getStartTime();
		RWLockThread[]	threadList	= new RWLockThread[5];
		threadList[0] = new RWLockThread("R0", false,	timeStart, 20, 20, 50);
		threadList[1] = new RWLockThread("R1", false,	timeStart, 25, 25, 60);
		threadList[2] = new RWLockThread("W2", true,	timeStart, 30, 60, 70);
		threadList[3] = new RWLockThread("R3", false,	timeStart, 35, 70, 80);
		threadList[4] = new RWLockThread("R4", false,	timeStart, 40, 70, 90);

		validateThreadList(threadList, 5);
	}

	@Test
	public void testWRW()
	{
		logTestName();

		long			timeStart	= getStartTime();
		RWLockThread[]	threadList	= new RWLockThread[5];
		threadList[0] = new RWLockThread("W0", true,	timeStart, 20, 20, 50);
		threadList[1] = new RWLockThread("W1", true,	timeStart, 25, 50, 60);
		threadList[2] = new RWLockThread("R2", false,	timeStart, 30, 60, 70);
		threadList[3] = new RWLockThread("W3", true,	timeStart, 35, 70, 80);
		threadList[4] = new RWLockThread("W4", true,	timeStart, 40, 80, 90);

		validateThreadList(threadList, 5);
	}

	@Test
	public void testSinglePerformance()
	{
		String						testName	= logTestName();

		StringGroup					name		= new StringGroup(testName);
		LockCounterFamily			counter		= new LockCounterFamily(name);
		AbstractReadWriteLock[]		lockList	= new AbstractReadWriteLock[4];
		lockList[0] = new BasicReadWriteLock(counter);
		lockList[1] = new AtomicReadWriteLock(counter);
		counter.setEnabled(false);
		lockList[2] = new AtomicReadWriteLock(counter);
		lockList[3] = new FastReadWriteLock();

		int		iMax		= 10;
		int		cont		= 10 * 1000;
		for (int i = 0; i < iMax; i++)
		{
			for (int iLock = 0; iLock < lockList.length; iLock++)
			{
				measureSinglePerformance(lockList[iLock], cont);
			}
		}
	}
	private void measureSinglePerformance(AbstractReadWriteLock lock, int count)
	{
		long		t1			= System.nanoTime();
		for (int i = 0; i < count; i++)
		{
			IOperationContext		context		= lock.lockRead();
			lock.unlockRead(context, true);
		}
		long		t2			= System.nanoTime();
		long		durationNS	= t2 - t1;
		reportPerformance(lock.getClass().getSimpleName() + " Lock/Unlock cycle", durationNS, count, true);
	}
	@Test
	public void testMultiPerformance()
	{
		String						testName	= logTestName();
		StringGroup					name0		= new StringGroup(testName + ".0");
		StringGroup					name1		= new StringGroup(testName + ".1");
		StringGroup					name2		= new StringGroup(testName + ".2");
//		StringGroup					name3		= new StringGroup(testName + ".3");
		LockCounterFamily			counter0	= new LockCounterFamily(name0);
		LockCounterFamily			counter1	= new LockCounterFamily(name1);
		LockCounterFamily			counter2	= new LockCounterFamily(name2);
//		LockCounterFamily			counter3	= new LockCounterFamily(name3);
		counter0.setEnabled(false);

		AbstractReadWriteLock[]		lockList	= new AbstractReadWriteLock[5];
		lockList[0] = new FastReadWriteLock();
		lockList[1] = new AtomicReadWriteLock(counter0);
		lockList[2] = new AtomicReadWriteLock(counter1);
		lockList[3] = new PlainReadWriteLock();
		lockList[4] = new BasicReadWriteLock(counter2);

		StringBuilder		sbHeader		= new StringBuilder(132);
		sbHeader.append("Thread cnt   ");
		for (int i = 0; i < lockList.length; i++)
		{
			if (null != lockList[i])
			{
				sbHeader.append(String.format("%7s ",
						lockList[i].getClass().getSimpleName().replace("ReadWriteLock", "")));
			}
		}
		getLogger().info(BasicEvent.EVENT_TEST, sbHeader.toString());

		int[]						threadCountList		= { 1, 2, 3, 4, 6, 8 };
		int							durationMS			= 1000;

		// Warm-up pass
		for (int i = 0; i < lockList.length; i++)
		{
			if (null != lockList[i])
			{
				measureMultiPerformance(lockList[i], 2, durationMS);
			}
		}

		for (int threadCount : threadCountList)
		{
			StringBuilder		sb		= new StringBuilder(132);
			sb.append(String.format("%,2d threads = ", threadCount));
			for (int i = 0; i < lockList.length; i++)
			{
				if (null != lockList[i])
				{
					long nsPer = measureMultiPerformance(lockList[i], threadCount, durationMS);
					sb.append(String.format("%,7d ", nsPer));
				}
			}
			sb.append("ns / Lock/Unlock cycle");
			getLogger().info(BasicEvent.EVENT_TEST, sb.toString());
		}
	}
	public long measureMultiPerformance(AbstractReadWriteLock lock, int threadCount, long durationMS)
	{
		PerformanceRWLockThread[]		threadList		= new PerformanceRWLockThread[threadCount + 1];
		// Thread 0 is the write thread
		threadList[0] = new PerformanceRWLockThread(lock, durationMS, false, 100);
		for (int i = 0; i < threadCount; i++)
		{
			threadList[i + 1] = new PerformanceRWLockThread(lock, durationMS, true, 0);
		}
		// Wait for ALL the thread to be done
		for (int i = 0; i < threadCount; i++)
		{
			threadList[i].waitUntilDone();
		}

		// Count only the READ threads
		long		count		= 0;
		for (int i = 0; i < threadCount; i++)
		{
			count += threadList[i + 1].getLoopCount();
		}
		String		message		= String.format("%s(%,d)", lock.getClass().getSimpleName(), threadCount);
		long		nsPer		= reportPerformance(message, durationMS * 1000 * 1000, count, false);
		return nsPer;
	}

	private long getStartTime()
	{
		long			now			= System.currentTimeMillis();
		long			timeStart	= now - (now % 100) + 200;
		return timeStart;
	}
	private void validateThreadList(RWLockThread[] threadList, int tolerance)
	{
		for (RWLockThread thread : threadList)
		{
			thread.waitUntilDone();
			if (!thread.m_isDone)
			{
				thread.validate(tolerance);
			}
		}
	}

	public static class RWLockThread extends AbstractBaseThread
	{
		private volatile boolean	m_isWrite;
		private volatile long		m_timeStart;
		private volatile long		m_timeAsk;
		private volatile long		m_expectedGetTime;
		private volatile long		m_actualGet;
		private volatile long		m_timeRelease;
		private volatile boolean	m_isDone			= false;
		private volatile long		m_actualRelease;

		public RWLockThread(String name,
				boolean isWrite, long timeStart, long timeAsk, long expectedGetTime, long timeRelease)
		{
			m_isWrite = isWrite;
			m_timeStart = timeStart;
			m_timeAsk = timeAsk;
			m_expectedGetTime = expectedGetTime;
			m_timeRelease = timeRelease;

			setName(String.format("%s[%s]", name, toString()));
			start();
		}

		@Override
		public void run()
		{
			waitUntil(m_timeStart + m_timeAsk);

//			getLogger().info(BasicEvent.EVENT_TEST, "Asking for lock: %s", toString());
			IOperationContext	context			= m_isWrite ? getLock().lockWrite() : getLock().lockRead();

//			getLogger().info(BasicEvent.EVENT_TEST, "Got        lock: %s", toString());
			m_actualGet = System.currentTimeMillis() - m_timeStart;
			waitUntil(m_timeStart + m_timeRelease);

//			getLogger().info(BasicEvent.EVENT_TEST, "Releasing  lock: %s", toString());
			if (m_isWrite)
			{
				getLock().unlockWrite(context, true);
			}
			else
			{
				getLock().unlockRead(context, true);
			}
			m_actualRelease = System.currentTimeMillis() - m_timeStart;
			m_isDone = true;
		}
		private void waitUntil(long timeMS)
		{
			while (System.currentTimeMillis() < timeMS)
			{
				BasicTools.sleepMS(1);
			}
		}

		public long getActualGet()
		{
			return m_actualGet;
		}

		public long getTimeRelease()
		{
			return m_timeRelease;
		}

		public long getActualRelease()
		{
			return m_actualRelease;
		}

		public void waitUntilDone()
		{
			while (!m_isDone)
			{
				BasicTools.sleepMS(5);
			}
		}

		public void validate(int tolerance)
		{
			getLogger().info(BasicEvent.EVENT_TEST, "Validating %s to within %d", toString(), tolerance);
			assertTrue(getName(), getActualGet() >= m_expectedGetTime - tolerance);
			assertTrue(getName(), getActualGet() <=  m_expectedGetTime + tolerance);
			assertTrue(getName(), getActualRelease() >= Math.max(getActualGet(), getTimeRelease()) - tolerance);
			assertTrue(getName(), getActualRelease() <= Math.max(getActualGet(), getTimeRelease()) + tolerance);
		}

		@Override
		public final String toString()
		{
			return String.format("%s(%s: %d, %d/%d, %d/%d)",
					m_isWrite ? "WriteLock" : "ReadLock ",
					m_isDone ? "Done" : "In progress",
					m_timeAsk, m_expectedGetTime, m_actualGet, m_timeRelease, m_actualRelease);
		}
	}

	public static class PerformanceRWLockThread extends AbstractBaseThread
	{
		private AbstractReadWriteLock	m_lock;
		private long					m_durationMS;
		private boolean					m_isRead;
		private int						m_sleepMS;

		private volatile long			m_loopCount		= 0;
		private volatile boolean		m_isDone		= false;

		public PerformanceRWLockThread(AbstractReadWriteLock lock, long durationMS, boolean isRead, int sleepMS)
		{
			m_lock = lock;
			m_durationMS = durationMS;
			m_isRead = isRead;
			m_sleepMS = sleepMS;

			start();
		}

		@Override
		public void run()
		{
			long		timeStartMS		= System.currentTimeMillis();
			long		timeEndMS		= timeStartMS + m_durationMS;
			while (System.currentTimeMillis() < timeEndMS)
			{
				m_loopCount++;
				if (m_isRead)
				{
					IOperationContext		context		= m_lock.lockRead();
					m_lock.unlockRead(context, true);
				}
				else
				{
					IOperationContext		context		= m_lock.lockWrite();
					m_lock.unlockWrite(context, true);
				}
				if (0 != m_sleepMS)
				{
					BasicTools.sleepMS(m_sleepMS);
				}
			}
			m_isDone = true;
		}

		public void waitUntilDone()
		{
			while (!m_isDone)
			{
				BasicTools.sleepMS(5);
			}
		}

		public long getLoopCount()
		{
			return m_loopCount;
		}
	}

}

redpajama_set_name: RedPajamaGithub


text:
package org.elasticsearch.repositories;

import org.apache.lucene.index.IndexCommit;
import org.elasticsearch.Version;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.ClusterStateUpdateTask;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.Metadata;
import org.elasticsearch.cluster.metadata.RepositoryMetadata;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.component.Lifecycle;
import org.elasticsearch.common.component.LifecycleListener;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.index.snapshots.IndexShardSnapshotStatus;
import org.elasticsearch.index.store.Store;
import org.elasticsearch.indices.recovery.RecoveryState;
import org.elasticsearch.snapshots.SnapshotId;
import org.elasticsearch.snapshots.SnapshotInfo;

import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;

public class FilterRepository implements Repository {

    private final Repository in;

    public FilterRepository(Repository in) {
        this.in = in;
    }

    @Override
    public RepositoryMetadata getMetadata() {
        return in.getMetadata();
    }

    @Override
    public SnapshotInfo getSnapshotInfo(SnapshotId snapshotId) {
        return in.getSnapshotInfo(snapshotId);
    }

    @Override
    public Metadata getSnapshotGlobalMetadata(SnapshotId snapshotId) {
        return in.getSnapshotGlobalMetadata(snapshotId);
    }

    @Override
    public IndexMetadata getSnapshotIndexMetaData(RepositoryData repositoryData, SnapshotId snapshotId, IndexId index) throws IOException {
        return in.getSnapshotIndexMetaData(repositoryData, snapshotId, index);
    }

    @Override
    public void getRepositoryData(ActionListener<RepositoryData> listener) {
        in.getRepositoryData(listener);
    }

    @Override
    public void finalizeSnapshot(ShardGenerations shardGenerations, long repositoryStateId, Metadata clusterMetadata,
                                 SnapshotInfo snapshotInfo, Version repositoryMetaVersion,
                                 Function<ClusterState, ClusterState> stateTransformer, ActionListener<RepositoryData> listener) {
        in.finalizeSnapshot(shardGenerations, repositoryStateId, clusterMetadata, snapshotInfo, repositoryMetaVersion, stateTransformer,
            listener);
    }

    @Override
    public void deleteSnapshots(Collection<SnapshotId> snapshotIds, long repositoryStateId, Version repositoryMetaVersion,
                                ActionListener<RepositoryData> listener) {
        in.deleteSnapshots(snapshotIds, repositoryStateId, repositoryMetaVersion, listener);
    }

    @Override
    public long getSnapshotThrottleTimeInNanos() {
        return in.getSnapshotThrottleTimeInNanos();
    }

    @Override
    public long getRestoreThrottleTimeInNanos() {
        return in.getRestoreThrottleTimeInNanos();
    }

    @Override
    public String startVerification() {
        return in.startVerification();
    }

    @Override
    public void endVerification(String verificationToken) {
        in.endVerification(verificationToken);
    }

    @Override
    public void verify(String verificationToken, DiscoveryNode localNode) {
        in.verify(verificationToken, localNode);
    }

    @Override
    public boolean isReadOnly() {
        return in.isReadOnly();
    }

    @Override
    public void snapshotShard(Store store, MapperService mapperService, SnapshotId snapshotId, IndexId indexId,
                              IndexCommit snapshotIndexCommit, String shardStateIdentifier, IndexShardSnapshotStatus snapshotStatus,
                              Version repositoryMetaVersion, Map<String, Object> userMetadata, ActionListener<String> listener) {
        in.snapshotShard(store, mapperService, snapshotId, indexId, snapshotIndexCommit, shardStateIdentifier, snapshotStatus,
            repositoryMetaVersion, userMetadata, listener);
    }
    @Override
    public void restoreShard(Store store, SnapshotId snapshotId, IndexId indexId, ShardId snapshotShardId, RecoveryState recoveryState,
                             ActionListener<Void> listener) {
        in.restoreShard(store, snapshotId, indexId, snapshotShardId, recoveryState, listener);
    }

    @Override
    public IndexShardSnapshotStatus getShardSnapshotStatus(SnapshotId snapshotId, IndexId indexId, ShardId shardId) {
        return in.getShardSnapshotStatus(snapshotId, indexId, shardId);
    }

    @Override
    public void updateState(ClusterState state) {
        in.updateState(state);
    }

    @Override
    public void executeConsistentStateUpdate(Function<RepositoryData, ClusterStateUpdateTask> createUpdateTask, String source,
                                             Consumer<Exception> onFailure) {
        in.executeConsistentStateUpdate(createUpdateTask, source, onFailure);
    }

    @Override
    public void cloneShardSnapshot(SnapshotId source, SnapshotId target, RepositoryShardId shardId, String shardGeneration,
                                   ActionListener<String> listener) {
        in.cloneShardSnapshot(source, target, shardId, shardGeneration, listener);
    }

    @Override
    public Lifecycle.State lifecycleState() {
        return in.lifecycleState();
    }

    @Override
    public void addLifecycleListener(LifecycleListener listener) {
        in.addLifecycleListener(listener);
    }

    @Override
    public void removeLifecycleListener(LifecycleListener listener) {
        in.removeLifecycleListener(listener);
    }

    @Override
    public void start() {
        in.start();
    }

    @Override
    public void stop() {
        in.stop();
    }

    @Override
    public void close() {
        in.close();
    }
}


text:
import sbt._
import Keys._

object Transform {
  lazy val transformSources = TaskKey[Seq[File]]("transform-sources")
  lazy val inputSourceDirectories = SettingKey[Seq[File]]("input-source-directories")
  lazy val inputSourceDirectory = SettingKey[File]("input-source-directory")
  lazy val inputSources = TaskKey[Seq[File]]("input-sources")
  lazy val sourceProperties = TaskKey[Map[String, String]]("source-properties")

  lazy val transformResources = TaskKey[Seq[File]]("transform-resources")
  lazy val inputResourceDirectories = SettingKey[Seq[File]]("input-resource-directories")
  lazy val inputResourceDirectory = SettingKey[File]("input-resource-directory")
  lazy val inputResources = TaskKey[Seq[File]]("input-resources")
  lazy val resourceProperties = TaskKey[Map[String, String]]("resource-properties")

  lazy val conscriptConfigs = TaskKey[Unit]("conscript-configs")

  def conscriptSettings(launch: Reference) = Seq(
    conscriptConfigs <<= (managedResources in launch in Compile, sourceDirectory in Compile).map { (res, src) =>
      val source = res.find(_.getName == "sbt.boot.properties") getOrElse sys.error("No managed boot.properties file.")
      copyConscriptProperties(source, src / "conscript")
      ()
    }
  )
  def copyConscriptProperties(source: File, conscriptBase: File): Seq[File] =
    {
      IO.delete(conscriptBase)
      val pairs = Seq(
        "sbt.xMain" -> "xsbt",
        "sbt.ScriptMain" -> "scalas",
        "sbt.ConsoleMain" -> "screpl"
      )
      for ((main, dir) <- pairs) yield {
        val file = conscriptBase / dir / "launchconfig"
        copyPropertiesFile(source, main, file)
        file
      }
    }
  def copyPropertiesFile(source: File, newMain: String, target: File): Unit = {
    def subMain(line: String): String = if (line.trim.startsWith("class:")) "  class: " + newMain else line
    IO.writeLines(target, IO.readLines(source) map subMain)
  }

  def crossGenSettings = transSourceSettings ++ Seq(
    sourceProperties := Map("cross.package0" -> "sbt", "cross.package1" -> "cross")
  )
  def transSourceSettings = Seq(
    inputSourceDirectory := sourceDirectory.value / "input_sources",
    inputSourceDirectories <<= Seq(inputSourceDirectory).join,
    inputSources <<= inputSourceDirectories.map(dirs => (dirs ** (-DirectoryFilter)).get),
    fileMappings in transformSources <<= transformSourceMappings,
    transformSources <<= (fileMappings in transformSources, sourceProperties) map { (rs, props) =>
      rs map { case (in, out) => transform(in, out, props) }
    },
    sourceGenerators <+= transformSources
  )
  def transformSourceMappings = (inputSources, inputSourceDirectories, sourceManaged) map { (ss, sdirs, sm) =>
    ((ss --- sdirs) pair (rebase(sdirs, sm) | flat(sm))).toSeq
  }
  def configSettings = transResourceSettings ++ Seq(
    resourceProperties <<= (organization, version, scalaVersion, isSnapshot) map { (org, v, sv, isSnapshot) =>
      Map("org" -> org, "sbt.version" -> v, "scala.version" -> sv)
    }
  )
  def transResourceSettings = Seq(
    inputResourceDirectory := sourceDirectory.value / "input_resources",
    inputResourceDirectories <<= Seq(inputResourceDirectory).join,
    inputResources <<= inputResourceDirectories.map(dirs => (dirs ** (-DirectoryFilter)).get),
    fileMappings in transformResources <<= transformResourceMappings,
    transformResources <<= (fileMappings in transformResources, resourceProperties) map { (rs, props) =>
      rs map { case (in, out) => transform(in, out, props) }
    },
    resourceGenerators <+= transformResources
  )
  def transformResourceMappings = (inputResources, inputResourceDirectories, resourceManaged) map { (rs, rdirs, rm) =>
    ((rs --- rdirs) pair (rebase(rdirs, rm) | flat(rm))).toSeq
  }

  def transform(in: File, out: File, map: Map[String, String]): File =
    {
      def get(key: String): String = map.getOrElse(key, sys.error("No value defined for key '" + key + "'"))
      val newString = Property.replaceAllIn(IO.read(in), mtch => get(mtch.group(1)))
      if (Some(newString) != read(out))
        IO.write(out, newString)
      out
    }
  def read(file: File): Option[String] = try { Some(IO.read(file)) } catch { case _: java.io.IOException => None }
  lazy val Property = """\$\{\{([\w.-]+)\}\}""".r
}


text:
"use strict"

const template = require("./this.marko")
  , twpapi = require("../../lib/twpapi")

module.exports = (req, res, data) => {
  if (!data) data = {}

  twpapi.GetEmployees().then((result) => {
    data.employees = result.Results
    template.render(data, res)
  }, (error) => {
    log.error(`Error reading employees: ${error}`)
    data.employees = []
    template.render(data, res)
  })
}


text:
FactoryGirl.define do

  factory :user do
    sequence(:email) {|n| "user#{n}@indeos.es"}
    password 'secret'
  end

  factory :admin, parent: :user  do
    admin true
  end

  factory :app do
    sequence(:name) {|n| "app[#{n}]"}
  end

  factory :recipe do
    sequence(:name) {|n| "recipe[#{n}]"}
    content "#recipe_content"
  end

  factory :permission do
    user { build_stubbed :user }
    recipe { build_stubbed :recipe }
    action 'cap'
  end

end


text:
"""ML2 hierarchical binding

Revision ID: 2d2a8a565438
Revises: 4119216b7365
Create Date: 2014-08-24 21:56:36.422885

"""

# revision identifiers, used by Alembic.
revision = '2d2a8a565438'
down_revision = '4119216b7365'

from alembic import op
import sqlalchemy as sa
from sqlalchemy.engine import reflection

port_binding_tables = ['ml2_port_bindings', 'ml2_dvr_port_bindings']

def upgrade():

    inspector = reflection.Inspector.from_engine(op.get_bind())
    fk_name = [fk['name'] for fk in
               inspector.get_foreign_keys('ml2_port_bindings')
               if 'segment' in fk['constrained_columns']]
    fk_name_dvr = [fk['name'] for fk in
                   inspector.get_foreign_keys('ml2_dvr_port_bindings')
                   if 'segment' in fk['constrained_columns']]

    op.create_table(
        'ml2_port_binding_levels',
        sa.Column('port_id', sa.String(length=36), nullable=False),
        sa.Column('host', sa.String(length=255), nullable=False),
        sa.Column('level', sa.Integer(), autoincrement=False, nullable=False),
        sa.Column('driver', sa.String(length=64), nullable=True),
        sa.Column('segment_id', sa.String(length=36), nullable=True),
        sa.ForeignKeyConstraint(['port_id'], ['ports.id'], ondelete='CASCADE'),
        sa.ForeignKeyConstraint(['segment_id'], ['ml2_network_segments.id'],
                                ondelete='SET NULL'),
        sa.PrimaryKeyConstraint('port_id', 'host', 'level')
    )

    for table in port_binding_tables:
        op.execute((
            "INSERT INTO ml2_port_binding_levels "
            "SELECT port_id, host, 0 AS level, driver, segment AS segment_id "
            "FROM %s "
            "WHERE host <> '' "
            "AND driver <> '';"
        ) % table)

    op.drop_constraint(fk_name_dvr[0], 'ml2_dvr_port_bindings', 'foreignkey')
    op.drop_column('ml2_dvr_port_bindings', 'cap_port_filter')
    op.drop_column('ml2_dvr_port_bindings', 'segment')
    op.drop_column('ml2_dvr_port_bindings', 'driver')

    op.drop_constraint(fk_name[0], 'ml2_port_bindings', 'foreignkey')
    op.drop_column('ml2_port_bindings', 'driver')
    op.drop_column('ml2_port_bindings', 'segment')

def downgrade():

    dialect = op.get_context().bind.dialect.name

    op.add_column('ml2_port_bindings',
                  sa.Column('segment', sa.String(length=36), nullable=True))
    op.add_column('ml2_port_bindings',
                  sa.Column('driver', sa.String(length=64), nullable=True))
    op.create_foreign_key(
        name=None,
        source='ml2_port_bindings', referent='ml2_network_segments',
        local_cols=['segment'], remote_cols=['id'], ondelete='SET NULL'
    )

    op.add_column('ml2_dvr_port_bindings',
                  sa.Column('driver', sa.String(length=64), nullable=True))
    op.add_column('ml2_dvr_port_bindings',
                  sa.Column('segment', sa.String(length=36), nullable=True))
    op.add_column('ml2_dvr_port_bindings',
                  sa.Column('cap_port_filter', sa.Boolean, nullable=False))
    op.create_foreign_key(
        name=None,
        source='ml2_dvr_port_bindings', referent='ml2_network_segments',
        local_cols=['segment'], remote_cols=['id'], ondelete='SET NULL'
    )

    for table in port_binding_tables:
        if dialect == 'postgresql':
            op.execute((
                "UPDATE %s pb "
                "SET driver = pbl.driver, segment = pbl.segment_id "
                "FROM ml2_port_binding_levels pbl "
                "WHERE pb.port_id = pbl.port_id "
                "AND pb.host = pbl.host "
                "AND pbl.level = 0;"
            ) % table)
        else:
            op.execute((
                "UPDATE %s pb "
                "INNER JOIN ml2_port_binding_levels pbl "
                "ON pb.port_id = pbl.port_id "
                "AND pb.host = pbl.host "
                "AND pbl.level = 0 "
                "SET pb.driver = pbl.driver, pb.segment = pbl.segment_id;"
            ) % table)

    op.drop_table('ml2_port_binding_levels')


text:
<?php
namespace apache\shindig\common\sample;
use apache\shindig\common\BlobCrypter;
use apache\shindig\common\Config;

/**
 * This class provides basic binary blob encryption and decryption, for use with the security token
 *
 */
class BasicBlobCrypter extends BlobCrypter {
  //FIXME make this compatible with the java's blobcrypter

  // Labels for key derivation
  protected $CIPHER_KEY_LABEL = 0;
  protected $HMAC_KEY_LABEL = 1;

  /** Key used for time stamp (in seconds) of data */
  public $TIMESTAMP_KEY = "t";

  /** minimum length of master key */
  public $MASTER_KEY_MIN_LEN = 16;

  /** allow three minutes for clock skew */
  protected $CLOCK_SKEW_ALLOWANCE = 180;

  protected $UTF8 = "UTF-8";

  protected $cipherKey;
  protected $hmacKey;
  protected $allowPlaintextToken;

  public function __construct() {
    $this->cipherKey = Config::get('token_cipher_key');
    $this->hmacKey = Config::get('token_hmac_key');
    $this->allowPlaintextToken = Config::get('allow_plaintext_token');
  }

  /**
   * {@inheritDoc}
   */
  public function wrap(Array $in) {
    $encoded = $this->serializeAndTimestamp($in);
    if (! function_exists('mcrypt_module_open') && $this->allowPlaintextToken) {
      $cipherText = base64_encode($encoded);
    } else {
      $cipherText = Crypto::aes128cbcEncrypt($this->cipherKey, $encoded);
    }
    $hmac = Crypto::hmacSha1($this->hmacKey, $cipherText);
    $b64 = base64_encode($cipherText . $hmac);
    return $b64;
  }

  /**
   *
   * @param array $in
   * @return string
   */
  protected function serializeAndTimestamp(Array $in) {
    $encoded = "";
    foreach ($in as $key => $val) {
      $encoded .= urlencode($key) . "=" . urlencode($val) . "&";
    }
    $encoded .= $this->TIMESTAMP_KEY . "=" . time();
    return $encoded;
  }

  /**
   * {@inheritDoc}
   */
  public function unwrap($in, $maxAgeSec) {
    //TODO remove this once we have a better way to generate a fake token in the example files
    if ($this->allowPlaintextToken && count(explode(':', $in)) >= 7) {
      //Parses the security token in the form st=o:v:a:d:u:m:c
      $data = $this->parseToken($in);
      $out = array();
      $out['o'] = $data[0];
      $out['v'] = $data[1];
      $out['a'] = $data[2];
      $out['d'] = $data[3];
      $out['u'] = $data[4];
      $out['m'] = $data[5];
    } else {
      $bin = base64_decode($in);
      if (is_callable('mb_substr')) {
        $cipherText = mb_substr($bin, 0, - Crypto::$HMAC_SHA1_LEN, 'latin1');
        $hmac = mb_substr($bin, mb_strlen($cipherText, 'latin1'), Crypto::$HMAC_SHA1_LEN, 'latin1');
      } else {
        $cipherText = substr($bin, 0, - Crypto::$HMAC_SHA1_LEN);
        $hmac = substr($bin, strlen($cipherText));
      }
      Crypto::hmacSha1Verify($this->hmacKey, $cipherText, $hmac);
      if (! function_exists('mcrypt_module_open') && $this->allowPlaintextToken) {
        $plain = base64_decode($cipherText);
      } else {
        $plain = Crypto::aes128cbcDecrypt($this->cipherKey, $cipherText);
      }
      $out = $this->deserialize($plain);
      $this->checkTimestamp($out, $maxAgeSec);
    }
    return $out;
  }

  /**
   * Parses the security token
   * @param string $stringToken
   * @return array
   */
  protected function parseToken($stringToken) {
    $data = explode(":", $stringToken);
       $url_number = count($data)-6;

	//get array elements conrresponding to broken url - http://host:port/gadget.xml -> ["http","//host","port/gadget.xml"]
	$url_array = array_slice($data,4,$url_number) ;
	$url = implode(":",$url_array);
	array_splice($data,4,$url_number,$url);
    return $data;
  }

  /**
   * @param string $plain
   * @return array
   */
  protected function deserialize($plain) {
    $map = array();
    parse_str($plain, $map);
    return $map;
  }

  /**
   *
   * @param array $out
   * @param int $maxAge
   * @throws BlobExpiredException
   */
  protected function checkTimestamp(Array $out, $maxAge) {
    $minTime = (int)$out[$this->TIMESTAMP_KEY] - $this->CLOCK_SKEW_ALLOWANCE;
    $maxTime = (int)$out[$this->TIMESTAMP_KEY] + $maxAge + $this->CLOCK_SKEW_ALLOWANCE;
    $now = time();
    if (! ($minTime < $now && $now < $maxTime)) {
      throw new BlobExpiredException("Security token expired");
    }
  }
}


text:
初始化,在运行时不改变

```assembly
section.data
```

## bss section

声名变量

```assembly
section.bss
```

## text section

代码段,必须有 `global _start` 告诉程序开始的地方

```
section.text
   global _start
_start:
```

## 注释

```assembly
; This program displays a message on screen
```

## `elf32`: Executable and Linkable Format 32-bit Object Files


text:
using Guitar32.Common;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;

namespace TestProject1
{

    ///
    ///This is a test class for IMonitorableTest and is intended
    ///to contain all IMonitorableTest Unit Tests
    ///
    [TestClass()]
    public class IMonitorableTest
    {

        private TestContext testContextInstance;

        ///
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///
        public TestContext TestContext {
            get {
                return testContextInstance;
            }
            set {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        internal virtual IMonitorable CreateIMonitorable() {
            // TODO: Instantiate an appropriate concrete class.
            IMonitorable target = null;
            return target;
        }

        ///
        ///A test for InitializeMonitors
        ///
        [TestMethod()]
        public void InitializeMonitorsTest() {
            IMonitorable target = CreateIMonitorable(); // TODO: Initialize to an appropriate value
            target.InitializeMonitors();
            Assert.Inconclusive("A method that does not return a value cannot be verified.");
        }
    }
}


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
Feddes Repert. Spec. Nov. Regni Veg. 97(7-8): 401 (1986)

#### Original name
Xerula hongoi Dörfelt

### Remarks
null


text:
function [trainingSet, validationSet, window_trainingSet, window_testingSet] = createDataset (Q, label, strideSize, windowSize)

trainingVec = [];
validationVec = [];
window_trainingVec = [];
window_testingVec = [];
trainingDuration = windowSize * 10;
testingDuration = windowSize * 5;

% Volume normalization
Q = normc(Q);

for col=1:trainingDuration+testingDuration: size(Q,2)
    trainingVec = cat(2, trainingVec, Q(:, col : min(col + trainingDuration - 1, size(Q, 2))));
    for i=col:strideSize:min(col+trainingDuration-windowSize, size(Q,2)-windowSize+1)
        window_trainingVec = cat(2,window_trainingVec,reshape(Q(:,i:i+windowSize-1),169*windowSize,1));
    end

    if col + trainingDuration - 1 >= size(Q, 2)
    	break
    end

    validationVec = cat(2, validationVec, ...
    	Q(:, col + trainingDuration : min(col + trainingDuration + testingDuration - 1, size(Q, 2))));
    for i=col+trainingDuration+1:strideSize:min(col+trainingDuration+testingDuration-windowSize,size(Q,2)-windowSize+1)
        window_testingVec = cat(2,window_testingVec,reshape(Q(:,i:i+windowSize-1),169*windowSize,1));
    end
end

% Add labels
trainingLabel = ones(size(trainingVec',1), 1) * label;
validationLabel = ones(size(validationVec',1), 1) * label;
window_trainingLabel = ones(size(window_trainingVec',1), 1) * label;
window_testingLabel = ones(size(window_testingVec',1), 1) * label;

trainingSet = [trainingVec' trainingLabel];
validationSet = [validationVec' validationLabel];
window_trainingSet = [window_trainingVec' window_trainingLabel];
window_testingSet = [window_testingVec' window_testingLabel];

disp(size(trainingSet));
disp(size(validationSet));
disp(size(window_trainingSet));
disp(size(window_testingSet));


text:
//The MIT License(MIT)

//copyright(c) 2016 Alberto Rodriguez

//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:

//The above copyright notice and this permission notice shall be included in all
//copies or substantial portions of the Software.

//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.

using System.Windows.Media;

namespace LiveCharts.Wpf
{
    /// <summary>
    /// Contains an already defined collection of geometries, useful to set the Series.PointGeomety property
    /// </summary>
    public static class DefaultGeometries
    {
        /// <summary>
        /// Returns a null geometry
        /// </summary>
        public static Geometry None
        {
            get { return null; }
        }

        /// <summary>
        /// Returns a circle geometry
        /// </summary>
        public static Geometry Circle
        {
            get { return Geometry.Parse("M 0,0 A 180,180 180 1 1 1,1 Z"); }
        }

        /// <summary>
        /// Returns a square geometry
        /// </summary>
        public static Geometry Square
        {
            get { return Geometry.Parse("M 1,1 h -2 v -2 h 2 z"); }
        }

        /// <summary>
        /// Returns a diamond property
        /// </summary>
        public static Geometry Diamond
        {
            get { return Geometry.Parse("M 1,0 L 2,1  1,2  0,1 z"); }
        }

        /// <summary>
        /// Returns a triangle geometry
        /// </summary>
        public static Geometry Trangle
        {
            get { return Geometry.Parse("M 0,1 l 1,1 h -2 Z"); }
        }
    }
}


text:
@implementation StreamEvent

- (NSMutableDictionary*)createBaseEventPayload {
    NSMutableDictionary *dict = @{}.mutableCopy;
    if (self.feedId != nil) {
        dict[@"feed_id"] = self.feedId;
    }
    if (self.location != nil) {
        dict[@"location"] = self.location;
    }
    if (self.position != nil) {
        dict[@"position"] = self.position;
    }
    if (self.features != nil) {
        dict[@"features"] = self.features;
    }
    return dict;
};

@end


text:
package discovery

import (
	"bytes"
	"fmt"
	"hash/crc32"
	"sort"
	"strings"
	"sync"
	"time"

	"context"

	"vitess.io/vitess/go/trace"

	"vitess.io/vitess/go/vt/key"
	"vitess.io/vitess/go/vt/log"
	"vitess.io/vitess/go/vt/topo"
	"vitess.io/vitess/go/vt/topo/topoproto"

	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
)

// tabletInfo is used internally by the TopologyWatcher class
type legacyTabletInfo struct {
	alias  string
	key    string
	tablet *topodatapb.Tablet
}

// NewLegacyCellTabletsWatcher returns a LegacyTopologyWatcher that monitors all
// the tablets in a cell, and starts refreshing.
func NewLegacyCellTabletsWatcher(ctx context.Context, topoServer *topo.Server, tr LegacyTabletRecorder, cell string, refreshInterval time.Duration, refreshKnownTablets bool, topoReadConcurrency int) *LegacyTopologyWatcher {
	return NewLegacyTopologyWatcher(ctx, topoServer, tr, cell, refreshInterval, refreshKnownTablets, topoReadConcurrency, func(tw *LegacyTopologyWatcher) ([]*topodatapb.TabletAlias, error) {
		return tw.topoServer.GetTabletsByCell(ctx, tw.cell)
	})
}

// NewLegacyShardReplicationWatcher returns a LegacyTopologyWatcher that
// monitors the tablets in a cell/keyspace/shard, and starts refreshing.
func NewLegacyShardReplicationWatcher(ctx context.Context, topoServer *topo.Server, tr LegacyTabletRecorder, cell, keyspace, shard string, refreshInterval time.Duration, topoReadConcurrency int) *LegacyTopologyWatcher {
	return NewLegacyTopologyWatcher(ctx, topoServer, tr, cell, refreshInterval, true /* RefreshKnownTablets */, topoReadConcurrency, func(tw *LegacyTopologyWatcher) ([]*topodatapb.TabletAlias, error) {
		sri, err := tw.topoServer.GetShardReplication(ctx, tw.cell, keyspace, shard)
		switch {
		case err == nil:
			// we handle this case after this switch block
		case topo.IsErrType(err, topo.NoNode):
			// this is not an error
			return nil, nil
		default:
			return nil, err
		}

		result := make([]*topodatapb.TabletAlias, len(sri.Nodes))
		for i, node := range sri.Nodes {
			result[i] = node.TabletAlias
		}
		return result, nil
	})
}

// LegacyTopologyWatcher polls tablet from a configurable set of tablets
// periodically. When tablets are added / removed, it calls
// the LegacyTabletRecorder AddTablet / RemoveTablet interface appropriately.
type LegacyTopologyWatcher struct {
	// set at construction time
	topoServer          *topo.Server
	tr                  LegacyTabletRecorder
	cell                string
	refreshInterval     time.Duration
	refreshKnownTablets bool
	getTablets          func(tw *LegacyTopologyWatcher) ([]*topodatapb.TabletAlias, error)
	sem                 chan int
	ctx                 context.Context
	cancelFunc          context.CancelFunc
	// wg keeps track of all launched Go routines.
	wg sync.WaitGroup

	// mu protects all variables below
	mu sync.Mutex
	// tablets contains a map of alias -> tabletInfo for all known tablets
	tablets map[string]*legacyTabletInfo
	// topoChecksum stores a crc32 of the tablets map and is exported as a metric
	topoChecksum uint32
	// lastRefresh records the timestamp of the last topo refresh
	lastRefresh time.Time
	// firstLoadDone is true when first load of the topology data is done.
	firstLoadDone bool
	// firstLoadChan is closed when the initial loading of topology data is done.
	firstLoadChan chan struct{}
}

// NewLegacyTopologyWatcher returns a LegacyTopologyWatcher that monitors all
// the tablets in a cell, and starts refreshing.
func NewLegacyTopologyWatcher(ctx context.Context, topoServer *topo.Server, tr LegacyTabletRecorder, cell string, refreshInterval time.Duration, refreshKnownTablets bool, topoReadConcurrency int, getTablets func(tw *LegacyTopologyWatcher) ([]*topodatapb.TabletAlias, error)) *LegacyTopologyWatcher {
	tw := &LegacyTopologyWatcher{
		topoServer:          topoServer,
		tr:                  tr,
		cell:                cell,
		refreshInterval:     refreshInterval,
		refreshKnownTablets: refreshKnownTablets,
		getTablets:          getTablets,
		sem:                 make(chan int, topoReadConcurrency),
		tablets:             make(map[string]*legacyTabletInfo),
	}
	tw.firstLoadChan = make(chan struct{})

	// We want the span from the context, but not the cancelation that comes with it
	spanContext := trace.CopySpan(context.Background(), ctx)
	tw.ctx, tw.cancelFunc = context.WithCancel(spanContext)
	tw.wg.Add(1)
	go tw.watch()
	return tw
}

// watch polls all tablets and notifies LegacyTabletRecorder by adding/removing tablets.
func (tw *LegacyTopologyWatcher) watch() {
	defer tw.wg.Done()
	ticker := time.NewTicker(tw.refreshInterval)
	defer ticker.Stop()
	for {
		tw.loadTablets()
		select {
		case <-tw.ctx.Done():
			return
		case <-ticker.C:
		}
	}
}

// loadTablets reads all tablets from topology, and updates LegacyTabletRecorder.
func (tw *LegacyTopologyWatcher) loadTablets() {
	var wg sync.WaitGroup
	newTablets := make(map[string]*legacyTabletInfo)
	replacedTablets := make(map[string]*legacyTabletInfo)

	tabletAliases, err := tw.getTablets(tw)
	topologyWatcherOperations.Add(topologyWatcherOpListTablets, 1)
	if err != nil {
		topologyWatcherErrors.Add(topologyWatcherOpListTablets, 1)
		select {
		case <-tw.ctx.Done():
			return
		default:
		}
		log.Errorf("cannot get tablets for cell: %v: %v", tw.cell, err)
		return
	}

	// Accumulate a list of all known alias strings to use later
	// when sorting
	tabletAliasStrs := make([]string, 0, len(tabletAliases))

	tw.mu.Lock()
	for _, tAlias := range tabletAliases {
		aliasStr := topoproto.TabletAliasString(tAlias)
		tabletAliasStrs = append(tabletAliasStrs, aliasStr)

		if !tw.refreshKnownTablets {
			if val, ok := tw.tablets[aliasStr]; ok {
				newTablets[aliasStr] = val
				continue
			}
		}

		wg.Add(1)
		go func(alias *topodatapb.TabletAlias) {
			defer wg.Done()
			tw.sem <- 1 // Wait for active queue to drain.
			tablet, err := tw.topoServer.GetTablet(tw.ctx, alias)
			topologyWatcherOperations.Add(topologyWatcherOpGetTablet, 1)
			<-tw.sem // Done; enable next request to run
			if err != nil {
				topologyWatcherErrors.Add(topologyWatcherOpGetTablet, 1)
				select {
				case <-tw.ctx.Done():
					return
				default:
				}
				log.Errorf("cannot get tablet for alias %v: %v", alias, err)
				return
			}
			tw.mu.Lock()
			aliasStr := topoproto.TabletAliasString(alias)
			newTablets[aliasStr] = &legacyTabletInfo{
				alias:  aliasStr,
				key:    TabletToMapKey(tablet.Tablet),
				tablet: tablet.Tablet,
			}
			tw.mu.Unlock()
		}(tAlias)
	}

	tw.mu.Unlock()
	wg.Wait()
	tw.mu.Lock()

	for alias, newVal := range newTablets {
		if val, ok := tw.tablets[alias]; !ok {
			// Check if there's a tablet with the same address key but a
			// different alias. If so, replace it and keep track of the
			// replaced alias to make sure it isn't removed later.
			found := false
			for _, otherVal := range tw.tablets {
				if newVal.key == otherVal.key {
					found = true
					tw.tr.ReplaceTablet(otherVal.tablet, newVal.tablet, alias)
					topologyWatcherOperations.Add(topologyWatcherOpReplaceTablet, 1)
					replacedTablets[otherVal.alias] = newVal
				}
			}
			if !found {
				tw.tr.AddTablet(newVal.tablet, alias)
				topologyWatcherOperations.Add(topologyWatcherOpAddTablet, 1)
			}

		} else if val.key != newVal.key {
			// Handle the case where the same tablet alias is now reporting
			// a different address key.
			replacedTablets[alias] = newVal
			tw.tr.ReplaceTablet(val.tablet, newVal.tablet, alias)
			topologyWatcherOperations.Add(topologyWatcherOpReplaceTablet, 1)
		}
	}

	for _, val := range tw.tablets {
		if _, ok := newTablets[val.alias]; !ok {
			if _, ok2 := replacedTablets[val.alias]; !ok2 {
				tw.tr.RemoveTablet(val.tablet)
				topologyWatcherOperations.Add(topologyWatcherOpRemoveTablet, 1)
			}
		}
	}
	tw.tablets = newTablets
	if !tw.firstLoadDone {
		tw.firstLoadDone = true
		close(tw.firstLoadChan)
	}

	// iterate through the tablets in a stable order and compute a
	// checksum of the tablet map
	sort.Strings(tabletAliasStrs)
	var buf bytes.Buffer
	for _, alias := range tabletAliasStrs {
		tabletInfo, ok := tw.tablets[alias]
		if ok {
			buf.WriteString(alias)
			buf.WriteString(tabletInfo.key)
		}
	}
	tw.topoChecksum = crc32.ChecksumIEEE(buf.Bytes())
	tw.lastRefresh = time.Now()

	tw.mu.Unlock()
}

// WaitForInitialTopology waits until the watcher reads all of the topology data
// for the first time and transfers the information to LegacyTabletRecorder via its
// AddTablet() method.
func (tw *LegacyTopologyWatcher) WaitForInitialTopology() error {
	select {
	case <-tw.ctx.Done():
		return tw.ctx.Err()
	case <-tw.firstLoadChan:
		return nil
	}
}

// Stop stops the watcher. It does not clean up the tablets added to LegacyTabletRecorder.
func (tw *LegacyTopologyWatcher) Stop() {
	tw.cancelFunc()
	// wait for watch goroutine to finish.
	tw.wg.Wait()
}

// RefreshLag returns the time since the last refresh
func (tw *LegacyTopologyWatcher) RefreshLag() time.Duration {
	tw.mu.Lock()
	defer tw.mu.Unlock()

	return time.Since(tw.lastRefresh)
}

// TopoChecksum returns the checksum of the current state of the topo
func (tw *LegacyTopologyWatcher) TopoChecksum() uint32 {
	tw.mu.Lock()
	defer tw.mu.Unlock()

	return tw.topoChecksum
}

// LegacyFilterByShard is a LegacyTabletRecorder filter that filters tablets by
// keyspace/shard.
type LegacyFilterByShard struct {
	// tr is the underlying LegacyTabletRecorder to forward requests too
	tr LegacyTabletRecorder

	// filters is a map of keyspace to filters for shards
	filters map[string][]*filterShard
}

// NewLegacyFilterByShard creates a new LegacyFilterByShard on top of an existing
// LegacyTabletRecorder. Each filter is a keyspace|shard entry, where shard
// can either be a shard name, or a keyrange. All tablets that match
// at least one keyspace|shard tuple will be forwarded to the
// underlying LegacyTabletRecorder.
func NewLegacyFilterByShard(tr LegacyTabletRecorder, filters []string) (*LegacyFilterByShard, error) {
	m := make(map[string][]*filterShard)
	for _, filter := range filters {
		parts := strings.Split(filter, "|")
		if len(parts) != 2 {
			return nil, fmt.Errorf("invalid LegacyFilterByShard parameter: %v", filter)
		}

		keyspace := parts[0]
		shard := parts[1]

		// extract keyrange if it's a range
		canonical, kr, err := topo.ValidateShardName(shard)
		if err != nil {
			return nil, fmt.Errorf("error parsing shard name %v: %v", shard, err)
		}

		// check for duplicates
		for _, c := range m[keyspace] {
			if c.shard == canonical {
				return nil, fmt.Errorf("duplicate %v/%v entry", keyspace, shard)
			}
		}

		m[keyspace] = append(m[keyspace], &filterShard{
			keyspace: keyspace,
			shard:    canonical,
			keyRange: kr,
		})
	}

	return &LegacyFilterByShard{
		tr:      tr,
		filters: m,
	}, nil
}

// AddTablet is part of the LegacyTabletRecorder interface.
func (fbs *LegacyFilterByShard) AddTablet(tablet *topodatapb.Tablet, name string) {
	if fbs.isIncluded(tablet) {
		fbs.tr.AddTablet(tablet, name)
	}
}

// RemoveTablet is part of the LegacyTabletRecorder interface.
func (fbs *LegacyFilterByShard) RemoveTablet(tablet *topodatapb.Tablet) {
	if fbs.isIncluded(tablet) {
		fbs.tr.RemoveTablet(tablet)
	}
}

// ReplaceTablet is part of the LegacyTabletRecorder interface.
func (fbs *LegacyFilterByShard) ReplaceTablet(old, new *topodatapb.Tablet, name string) {
	if fbs.isIncluded(old) && fbs.isIncluded(new) {
		fbs.tr.ReplaceTablet(old, new, name)
	}
}

// isIncluded returns true iff the tablet's keyspace and shard should be
// forwarded to the underlying LegacyTabletRecorder.
func (fbs *LegacyFilterByShard) isIncluded(tablet *topodatapb.Tablet) bool {
	canonical, kr, err := topo.ValidateShardName(tablet.Shard)
	if err != nil {
		log.Errorf("Error parsing shard name %v, will ignore tablet: %v", tablet.Shard, err)
		return false
	}

	for _, c := range fbs.filters[tablet.Keyspace] {
		if canonical == c.shard {
			// Exact match (probably a non-sharded keyspace).
			return true
		}
		if kr != nil && c.keyRange != nil && key.KeyRangeIncludes(c.keyRange, kr) {
			// Our filter's KeyRange includes the provided KeyRange
			return true
		}
	}
	return false
}

// LegacyFilterByKeyspace is a LegacyTabletRecorder filter that filters tablets by
// keyspace
type LegacyFilterByKeyspace struct {
	tr LegacyTabletRecorder

	keyspaces map[string]bool
}

// NewLegacyFilterByKeyspace creates a new LegacyFilterByKeyspace on top of an existing
// LegacyTabletRecorder. Each filter is a keyspace entry. All tablets that match
// a keyspace will be forwarded to the underlying LegacyTabletRecorder.
func NewLegacyFilterByKeyspace(tr LegacyTabletRecorder, selectedKeyspaces []string) *LegacyFilterByKeyspace {
	m := make(map[string]bool)
	for _, keyspace := range selectedKeyspaces {
		m[keyspace] = true
	}

	return &LegacyFilterByKeyspace{
		tr:        tr,
		keyspaces: m,
	}
}

// AddTablet is part of the LegacyTabletRecorder interface.
func (fbk *LegacyFilterByKeyspace) AddTablet(tablet *topodatapb.Tablet, name string) {
	if fbk.isIncluded(tablet) {
		fbk.tr.AddTablet(tablet, name)
	}
}

// RemoveTablet is part of the LegacyTabletRecorder interface.
func (fbk *LegacyFilterByKeyspace) RemoveTablet(tablet *topodatapb.Tablet) {
	if fbk.isIncluded(tablet) {
		fbk.tr.RemoveTablet(tablet)
	}
}

// ReplaceTablet is part of the LegacyTabletRecorder interface.
func (fbk *LegacyFilterByKeyspace) ReplaceTablet(old *topodatapb.Tablet, new *topodatapb.Tablet, name string) {
	if old.Keyspace != new.Keyspace {
		log.Errorf("Error replacing old tablet in %v with new tablet in %v", old.Keyspace, new.Keyspace)
		return
	}

	if fbk.isIncluded(new) {
		fbk.tr.ReplaceTablet(old, new, name)
	}
}

// isIncluded returns true if the tablet's keyspace should be
// forwarded to the underlying LegacyTabletRecorder.
func (fbk *LegacyFilterByKeyspace) isIncluded(tablet *topodatapb.Tablet) bool {
	_, exist := fbk.keyspaces[tablet.Keyspace]
	return exist
}


text:
namespace samples
{
	void MultiInheritanceExample();
}


text:
package es.upv.i3m.grycap.im.pojo;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;

import es.upv.i3m.grycap.im.exceptions.InfrastructureUuidNotFoundException;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class InfrastructureUri {

  private final String uri;
  private String infrastructureId;
  private static final String UUID_PATTERN =
      "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";

  public InfrastructureUri(@JsonProperty("uri") String uri) {
    this.uri = uri;
  }

  public String getUri() {
    return uri;
  }

  /**
   * Returns the infrastructure Id extracted from the infrastructure uri.
   */
  public String getInfrastructureId()
      throws InfrastructureUuidNotFoundException {
    if (infrastructureId == null) {
      infrastructureId = extractInfrastructureId();
    }
    return infrastructureId;
  }

  private String extractInfrastructureId()
      throws InfrastructureUuidNotFoundException {
    Pattern ptrn = Pattern.compile(UUID_PATTERN);
    Matcher matcher = ptrn.matcher(uri);
    if (matcher.find()) {
      return matcher.group(0);
    }
    throw new InfrastructureUuidNotFoundException();
  }

  @Override
  public String toString() {
    return ToStringBuilder.reflectionToString(this);
  }

  @Override
  public int hashCode() {
    return new HashCodeBuilder().append(uri).toHashCode();
  }

  @Override
  public boolean equals(Object other) {
    if (other == this) {
      return true;
    }
    if (other instanceof InfrastructureUri) {
      InfrastructureUri infUri = (InfrastructureUri) other;
      return new EqualsBuilder().append(uri, infUri.uri).isEquals();
    }
    return false;
  }
}


text:
package com.duomn.entity;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

@Entity
@Table(name="tbl_user")
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class UserModel implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="id", nullable = false)
	private int id;

	@Column(name="username")
	private String username;

	@Column(name="email")
    private String email;

	@Column(name="password")
    private String password;

	@Column(name="register_date")
    private Date registerDate;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public Date getRegisterDate() {
		return registerDate;
	}

	public void setRegisterDate(Date registerDate) {
		this.registerDate = registerDate;
	}

	@Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + id;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        UserModel other = (UserModel) obj;
        if (id != other.id)
            return false;
        return true;
    }

}


text:
package io.machinecode.chainlink.core.jsl.fluent;

import io.machinecode.chainlink.core.jsl.fluent.execution.FluentDecision;
import io.machinecode.chainlink.core.jsl.fluent.execution.FluentFlow;
import io.machinecode.chainlink.core.jsl.fluent.execution.FluentSplit;
import io.machinecode.chainlink.core.jsl.fluent.execution.FluentStep;
import io.machinecode.chainlink.core.jsl.fluent.partition.FluentAnalyser;
import io.machinecode.chainlink.core.jsl.fluent.partition.FluentCollector;
import io.machinecode.chainlink.core.jsl.fluent.partition.FluentMapper;
import io.machinecode.chainlink.core.jsl.fluent.partition.FluentPartition;
import io.machinecode.chainlink.core.jsl.fluent.partition.FluentPlan;
import io.machinecode.chainlink.core.jsl.fluent.partition.FluentReducer;
import io.machinecode.chainlink.core.jsl.fluent.task.FluentBatchlet;
import io.machinecode.chainlink.core.jsl.fluent.task.FluentCheckpointAlgorithm;
import io.machinecode.chainlink.core.jsl.fluent.task.FluentChunk;
import io.machinecode.chainlink.core.jsl.fluent.task.FluentExceptionClass;
import io.machinecode.chainlink.core.jsl.fluent.task.FluentExceptionClassFilter;
import io.machinecode.chainlink.core.jsl.fluent.task.FluentItemProcessor;
import io.machinecode.chainlink.core.jsl.fluent.task.FluentItemReader;
import io.machinecode.chainlink.core.jsl.fluent.task.FluentItemWriter;
import io.machinecode.chainlink.core.jsl.fluent.transition.FluentEnd;
import io.machinecode.chainlink.core.jsl.fluent.transition.FluentFail;
import io.machinecode.chainlink.core.jsl.fluent.transition.FluentNext;
import io.machinecode.chainlink.core.jsl.fluent.transition.FluentStop;

/**
 * @author Brent Douglas
 * @since 1.0
 */
public class Jsl {

    public static FluentJob job(final String id) {
        return new FluentJob().setId(id);
    }

    public static FluentListener listener(final String ref) {
        return new FluentListener().setRef(ref);
    }

    public static FluentListeners listeners() {
        return new FluentListeners();
    }

    public static FluentProperty property() {
        return new FluentProperty();
    }

    public static FluentProperties properties() {
        return new FluentProperties();
    }

    // Execution

    public static FluentDecision decision(final String id) {
        return new FluentDecision().setId(id);
    }

    public static FluentFlow flow(final String id) {
        return new FluentFlow().setId(id);
    }

    public static FluentSplit split(final String id) {
        return new FluentSplit().setId(id);
    }

    public static FluentStep step(final String id) {
        return new FluentStep().setId(id);
    }

    // Transition

    public static FluentEnd end() {
        return new FluentEnd();
    }

    public static FluentFail fail() {
        return new FluentFail();
    }

    public static FluentNext next() {
        return new FluentNext();
    }

    public static FluentStop stop() {
        return new FluentStop();
    }

    // Partition

    public static FluentAnalyser analyser(final String ref) {
        return new FluentAnalyser().setRef(ref);
    }

    public static FluentCollector collector(final String ref) {
        return new FluentCollector().setRef(ref);
    }

    public static FluentPartition partition() {
        return new FluentPartition();
    }

    public static FluentMapper mapper(final String ref) {
        return new FluentMapper().setRef(ref);
    }

    public static FluentPlan plan() {
        return new FluentPlan();
    }

    public static FluentReducer reducer(final String ref) {
        return new FluentReducer().setRef(ref);
    }

    // Task

    public static FluentBatchlet batchlet(final String ref) {
        return new FluentBatchlet().setRef(ref);
    }

    public static FluentCheckpointAlgorithm checkpointAlgorithm(final String ref) {
        return new FluentCheckpointAlgorithm().setRef(ref);
    }

    public static FluentChunk chunk() {
        return new FluentChunk();
    }

    public static FluentExceptionClass classes() {
        return new FluentExceptionClass();
    }

    public static FluentExceptionClassFilter filter() {
        return new FluentExceptionClassFilter();
    }

    public static FluentExceptionClassFilter skippableExceptionClasses() {
        return filter();
    }

    public static FluentExceptionClassFilter retryableExceptionClasses() {
        return filter();
    }

    public static FluentExceptionClassFilter noRollbackExceptionClasses() {
        return filter();
    }

    public static FluentItemProcessor processor(final String ref) {
        return new FluentItemProcessor().setRef(ref);
    }

    public static FluentItemReader reader(final String ref) {
        return new FluentItemReader().setRef(ref);
    }

    public static FluentItemWriter writer(final String ref) {
        return new FluentItemWriter().setRef(ref);
    }
}