text:
extern crate core;

pub mod aptos;
pub mod error;
pub mod faucet;

pub use faucet::FaucetClient;
pub mod response;
pub use response::Response;
pub mod state;
pub mod types;

pub use aptos_api_types::{
    self, IndexResponseBcs, MoveModuleBytecode, PendingTransaction, Transaction,
};
pub use state::State;
pub use types::{deserialize_from_prefixed_hex_string, Account, Resource};

use crate::aptos::{AptosVersion, Balance};
use crate::error::RestError;
use anyhow::{anyhow, Result};
use aptos_api_types::{
    deserialize_from_string,
    mime_types::{BCS, BCS_SIGNED_TRANSACTION as BCS_CONTENT_TYPE},
    AptosError, BcsBlock, Block, Bytecode, ExplainVMStatus, GasEstimation, HexEncodedBytes,
    IndexResponse, MoveModuleId, TransactionData, TransactionOnChainData,
    TransactionsBatchSubmissionResult, UserTransaction, VersionedEvent,
};
use aptos_crypto::HashValue;
use aptos_logger::{debug, info, sample, sample::SampleRate};
use aptos_types::{
    account_address::AccountAddress,
    account_config::{AccountResource, CoinStoreResource, NewBlockEvent, CORE_CODE_ADDRESS},
    contract_event::EventWithVersion,
    transaction::SignedTransaction,
};
use futures::executor::block_on;
use move_binary_format::CompiledModule;
use move_core_types::language_storage::{ModuleId, StructTag};
use reqwest::header::ACCEPT;
use reqwest::{header::CONTENT_TYPE, Client as ReqwestClient, StatusCode};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use serde_json::{json, Value};
use std::collections::BTreeMap;
use std::future::Future;
use std::rc::Rc;
use std::time::Duration;
use tokio::time::Instant;
use url::Url;

pub const USER_AGENT: &str = concat!("aptos-client-sdk-rust / ", env!("CARGO_PKG_VERSION"));
pub const DEFAULT_VERSION_PATH_BASE: &str = "v1/";
const DEFAULT_MAX_WAIT_MS: u64 = 60000;
const DEFAULT_INTERVAL_MS: u64 = 1000;
static DEFAULT_MAX_WAIT_DURATION: Duration = Duration::from_millis(DEFAULT_MAX_WAIT_MS);
static DEFAULT_INTERVAL_DURATION: Duration = Duration::from_millis(DEFAULT_INTERVAL_MS);
const DEFAULT_MAX_SERVER_LAG_WAIT_DURATION: Duration = Duration::from_secs(60);

type AptosResult<T> = Result<T, RestError>;

#[derive(Clone, Debug)]
pub struct Client {
    inner: ReqwestClient,
    base_url: Url,
    version_path_base: String,
}

impl Client {
    pub fn new_with_timeout(base_url: Url, timeout: Duration) -> Self {
        let inner = ReqwestClient::builder()
            .timeout(timeout)
            .user_agent(USER_AGENT)
            .cookie_store(true)
            .build()
            .unwrap();

        // If the user provided no version in the path, use the default. If the
        // provided version has no trailing slash, add it, otherwise url.join
        // will ignore the version path base.
        let version_path_base = match base_url.path() {
            "/" => DEFAULT_VERSION_PATH_BASE.to_string(),
            path => {
                if !path.ends_with('/') {
                    format!("{}/", path)
                } else {
                    path.to_string()
                }
            }
        };

        Self {
            inner,
            base_url,
            version_path_base,
        }
    }

    pub fn new(base_url: Url) -> Self {
        Self::new_with_timeout(base_url, Duration::from_secs(10))
    }

    pub fn path_prefix_string(&self) -> String {
        self.base_url
            .join(&self.version_path_base)
            .map(|path| path.to_string())
            .unwrap_or_else(|_| "<bad_base_url>".to_string())
    }

    /// Set a different version path base, e.g. "v1/" See
    /// DEFAULT_VERSION_PATH_BASE for the default value.
    pub fn version_path_base(mut self, version_path_base: String) -> AptosResult<Self> {
        if !version_path_base.ends_with('/') {
            return Err(anyhow!("version_path_base must end with '/', e.g. 'v1/'").into());
        }
        self.version_path_base = version_path_base;
        Ok(self)
    }

    fn build_path(&self, path: &str) -> AptosResult<Url> {
        Ok(self.base_url.join(&self.version_path_base)?.join(path)?)
    }

    pub async fn get_aptos_version(&self) -> AptosResult<Response<AptosVersion>> {
        self.get_resource::<AptosVersion>(CORE_CODE_ADDRESS, "0x1::version::Version")
            .await
    }

    pub async fn get_block_by_height(
        &self,
        height: u64,
        with_transactions: bool,
    ) -> AptosResult<Response<Block>> {
        self.get(self.build_path(&format!(
            "blocks/by_height/{}?with_transactions={}",
            height, with_transactions
        ))?)
        .await
    }

    pub async fn get_block_by_height_bcs(
        &self,
        height: u64,
        with_transactions: bool,
    ) -> AptosResult<Response<BcsBlock>> {
        let url = self.build_path(&format!(
            "blocks/by_height/{}?with_transactions={}",
            height, with_transactions
        ))?;
        let response = self.get_bcs(url).await?;
        Ok(response.and_then(|inner| bcs::from_bytes(&inner))?)
    }

    /// This will get all the transactions from the block in successive calls
    /// and will handle the successive calls
    ///
    /// Note: This could take a long time to run
    pub async fn get_full_block_by_height_bcs(
        &self,
        height: u64,
        page_size: u16,
    ) -> AptosResult<Response<BcsBlock>> {
        let (mut block, state) = self
            .get_block_by_height_bcs(height, true)
            .await?
            .into_parts();

        let mut current_version = block.first_version;

        // Set the current version to the last known transaction
        if let Some(ref txns) = block.transactions {
            if let Some(txn) = txns.last() {
                current_version = txn.version + 1;
            }
        } else {
            return Err(RestError::Unknown(anyhow!(
                "No transactions were returned in the block"
            )));
        }

        // Add in all transactions by paging through the other transactions
        while current_version <= block.last_version {
            let page_end_version =
                std::cmp::min(block.last_version, current_version + page_size as u64 - 1);

            let transactions = self
                .get_transactions_bcs(
                    Some(current_version),
                    Some((page_end_version - current_version + 1) as u16),
                )
                .await?
                .into_inner();
            if let Some(txn) = transactions.last() {
                current_version = txn.version + 1;
            };
            block.transactions.as_mut().unwrap().extend(transactions);
        }

        Ok(Response::new(block, state))
    }

    pub async fn get_block_by_version(
        &self,
        version: u64,
        with_transactions: bool,
    ) -> AptosResult<Response<Block>> {
        self.get(self.build_path(&format!(
            "blocks/by_version/{}?with_transactions={}",
            version, with_transactions
        ))?)
        .await
    }

    pub async fn get_block_by_version_bcs(
        &self,
        height: u64,
        with_transactions: bool,
    ) -> AptosResult<Response<BcsBlock>> {
        let url = self.build_path(&format!(
            "blocks/by_version/{}?with_transactions={}",
            height, with_transactions
        ))?;
        let response = self.get_bcs(url).await?;
        Ok(response.and_then(|inner| bcs::from_bytes(&inner))?)
    }

    pub async fn get_account_balance(
        &self,
        address: AccountAddress,
    ) -> AptosResult<Response<Balance>> {
        let resp = self
            .get_account_resource(address, "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>")
            .await?;
        resp.and_then(|resource| {
            if let Some(res) = resource {
                Ok(serde_json::from_value::<Balance>(res.data)?)
            } else {
                Err(anyhow!("No data returned").into())
            }
        })
    }

    pub async fn get_account_balance_bcs(
        &self,
        address: AccountAddress,
        coin_type: &str,
    ) -> AptosResult<Response<u64>> {
        let resp = self
            .get_account_resource_bcs::<CoinStoreResource>(
                address,
                &format!("0x1::coin::CoinStore<{}>", coin_type),
            )
            .await?;
        resp.and_then(|resource| Ok(resource.coin()))
    }

    pub async fn get_account_balance_at_version(
        &self,
        address: AccountAddress,
        version: u64,
    ) -> AptosResult<Response<Balance>> {
        let resp = self
            .get_account_resource_at_version(
                address,
                "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>",
                version,
            )
            .await?;
        resp.and_then(|resource| {
            if let Some(res) = resource {
                Ok(serde_json::from_value::<Balance>(res.data)?)
            } else {
                Err(anyhow!("No data returned").into())
            }
        })
    }

    pub async fn get_index(&self) -> AptosResult<Response<IndexResponse>> {
        self.get(self.build_path("")?).await
    }

    pub async fn get_index_bcs(&self) -> AptosResult<Response<IndexResponseBcs>> {
        let url = self.build_path("")?;
        let response = self.get_bcs(url).await?;
        Ok(response.and_then(|inner| bcs::from_bytes(&inner))?)
    }

    pub async fn get_ledger_information(&self) -> AptosResult<Response<State>> {
        let response = self.get_index_bcs().await?.map(|r| State {
            chain_id: r.chain_id,
            epoch: r.epoch.into(),
            version: r.ledger_version.into(),
            timestamp_usecs: r.ledger_timestamp.into(),
            oldest_ledger_version: r.oldest_ledger_version.into(),
            oldest_block_height: r.oldest_block_height.into(),
            block_height: r.block_height.into(),
        });
        assert_eq!(response.inner().chain_id, response.state().chain_id);
        assert_eq!(response.inner().epoch, response.state().epoch);
        assert_eq!(response.inner().version, response.state().version);
        assert_eq!(response.inner().block_height, response.state().block_height);

        Ok(response)
    }

    pub async fn simulate(
        &self,
        txn: &SignedTransaction,
    ) -> AptosResult<Response<Vec<UserTransaction>>> {
        let txn_payload = bcs::to_bytes(txn)?;
        let url = self.build_path("transactions/simulate")?;

        let response = self
            .inner
            .post(url)
            .header(CONTENT_TYPE, BCS_CONTENT_TYPE)
            .body(txn_payload)
            .send()
            .await?;

        self.json(response).await
    }

    pub async fn simulate_bcs(
        &self,
        txn: &SignedTransaction,
    ) -> AptosResult<Response<TransactionOnChainData>> {
        let txn_payload = bcs::to_bytes(txn)?;
        let url = self.build_path("transactions/simulate")?;

        let response = self
            .inner
            .post(url)
            .header(CONTENT_TYPE, BCS_CONTENT_TYPE)
            .header(ACCEPT, BCS)
            .body(txn_payload)
            .send()
            .await?;

        let response = self.check_and_parse_bcs_response(response).await?;
        Ok(response.and_then(|bytes| bcs::from_bytes(&bytes))?)
    }

    pub async fn simulate_bcs_with_gas_estimation(
        &self,
        txn: &SignedTransaction,
        estimate_max_gas_amount: bool,
        estimate_max_gas_unit_price: bool,
    ) -> AptosResult<Response<TransactionOnChainData>> {
        let txn_payload = bcs::to_bytes(txn)?;
        let url = self.build_path(&format!(
            "transactions/simulate?estimate_max_gas_amount={}&estimate_gas_unit_price={}",
            estimate_max_gas_amount, estimate_max_gas_unit_price
        ))?;

        let response = self
            .inner
            .post(url)
            .header(CONTENT_TYPE, BCS_CONTENT_TYPE)
            .header(ACCEPT, BCS)
            .body(txn_payload)
            .send()
            .await?;

        let response = self.check_and_parse_bcs_response(response).await?;
        Ok(response.and_then(|bytes| bcs::from_bytes(&bytes))?)
    }

    pub async fn submit(
        &self,
        txn: &SignedTransaction,
    ) -> AptosResult<Response<PendingTransaction>> {
        let txn_payload = bcs::to_bytes(txn)?;
        let url = self.build_path("transactions")?;

        let response = self
            .inner
            .post(url)
            .header(CONTENT_TYPE, BCS_CONTENT_TYPE)
            .body(txn_payload)
            .send()
            .await?;

        self.json(response).await
    }

    pub async fn submit_bcs(&self, txn: &SignedTransaction) -> AptosResult<Response<()>> {
        let txn_payload = bcs::to_bytes(txn)?;
        let url = self.build_path("transactions")?;

        let response = self
            .inner
            .post(url)
            .header(CONTENT_TYPE, BCS_CONTENT_TYPE)
            .header(ACCEPT, BCS)
            .body(txn_payload)
            .send()
            .await?;

        let response = self.check_and_parse_bcs_response(response).await?;
        Ok(response.and_then(|bytes| bcs::from_bytes(&bytes))?)
    }

    pub async fn submit_batch(
        &self,
        txns: &[SignedTransaction],
    ) -> AptosResult<Response<TransactionsBatchSubmissionResult>> {
        let txn_payload = bcs::to_bytes(&txns.to_vec())?;
        let url = self.build_path("transactions/batch")?;

        let response = self
            .inner
            .post(url)
            .header(CONTENT_TYPE, BCS_CONTENT_TYPE)
            .body(txn_payload)
            .send()
            .await?;
        self.json(response).await
    }
    pub async fn submit_batch_bcs(
        &self,
        txns: &[SignedTransaction],
    ) -> AptosResult<Response<TransactionsBatchSubmissionResult>> {
        let txn_payload = bcs::to_bytes(&txns.to_vec())?;
        let url = self.build_path("transactions/batch")?;

        let response = self
            .inner
            .post(url)
            .header(CONTENT_TYPE, BCS_CONTENT_TYPE)
            .header(ACCEPT, BCS)
            .body(txn_payload)
            .send()
            .await?;

        let response = self.check_and_parse_bcs_response(response).await?;
        Ok(response.and_then(|bytes| bcs::from_bytes(&bytes))?)
    }

    pub async fn submit_and_wait(
        &self,
        txn: &SignedTransaction,
    ) -> AptosResult<Response<Transaction>> {
        self.submit(txn).await?;
        self.wait_for_signed_transaction(txn).await
    }

    pub async fn submit_and_wait_bcs(
        &self,
        txn: &SignedTransaction,
    ) -> AptosResult<Response<TransactionOnChainData>> {
        self.submit_bcs(txn).await?;
        self.wait_for_signed_transaction_bcs(txn).await
    }

    pub async fn wait_for_transaction(
        &self,
        pending_transaction: &PendingTransaction,
    ) -> AptosResult<Response<Transaction>> {
        self.wait_for_transaction_by_hash(
            pending_transaction.hash.into(),
            *pending_transaction
                .request
                .expiration_timestamp_secs
                .inner(),
            Some(DEFAULT_MAX_SERVER_LAG_WAIT_DURATION),
            None,
        )
        .await
    }

    pub async fn wait_for_transaction_bcs(
        &self,
        pending_transaction: &PendingTransaction,
    ) -> AptosResult<Response<TransactionOnChainData>> {
        self.wait_for_transaction_by_hash_bcs(
            pending_transaction.hash.into(),
            *pending_transaction
                .request
                .expiration_timestamp_secs
                .inner(),
            Some(DEFAULT_MAX_SERVER_LAG_WAIT_DURATION),
            None,
        )
        .await
    }

    pub async fn wait_for_signed_transaction(
        &self,
        transaction: &SignedTransaction,
    ) -> AptosResult<Response<Transaction>> {
        let expiration_timestamp = transaction.expiration_timestamp_secs();
        self.wait_for_transaction_by_hash(
            transaction.clone().committed_hash(),
            expiration_timestamp,
            Some(DEFAULT_MAX_SERVER_LAG_WAIT_DURATION),
            None,
        )
        .await
    }

    pub async fn wait_for_signed_transaction_bcs(
        &self,
        transaction: &SignedTransaction,
    ) -> AptosResult<Response<TransactionOnChainData>> {
        let expiration_timestamp = transaction.expiration_timestamp_secs();
        self.wait_for_transaction_by_hash_bcs(
            transaction.clone().committed_hash(),
            expiration_timestamp,
            Some(DEFAULT_MAX_SERVER_LAG_WAIT_DURATION),
            None,
        )
        .await
    }

    /// Implementation of waiting for a transaction
    /// * `hash`: hash of the submitted transaction
    /// * `expiration_timestamp_secs`: expiration time of the submitted transaction
    /// * `max_server_lag_wait`:
    ///     Fullnodes generally lag some amount behind the authoritative blockchain ledger state.
    ///     This field gives the node some time to update its ledger state to the point
    ///     where your transaction might have expired.
    ///     We recommend setting this value to at least 60 seconds.
    /// * `timeout_from_call`:
    ///     When an absolute timeout for this function is needed,
    ///     irrespective of whether expiry time is reached.
    async fn wait_for_transaction_by_hash_inner<F, Fut, T>(
        &self,
        hash: HashValue,
        expiration_timestamp_secs: u64,
        max_server_lag_wait: Option<Duration>,

        timeout_from_call: Option<Duration>,
        fetch: F,
    ) -> AptosResult<Response<T>>
    where
        F: Fn(HashValue) -> Fut,
        Fut: Future<Output = AptosResult<WaitForTransactionResult<T>>>,
    {
        const DEFAULT_DELAY: Duration = Duration::from_millis(500);
        let mut reached_mempool = false;
        let start = std::time::Instant::now();
        loop {
            let mut chain_timestamp_usecs = None;
            match fetch(hash).await? {
                WaitForTransactionResult::Success(result) => {
                    return Ok(result);
                }
                WaitForTransactionResult::FailedExecution(vm_status) => {
                    return Err(anyhow!(
                        "Transaction committed on chain, but failed execution: {}",
                        vm_status
                    ))?;
                }
                WaitForTransactionResult::Pending(state) => {
                    reached_mempool = true;
                    if expiration_timestamp_secs <= state.timestamp_usecs / 1_000_000 {
                        return Err(anyhow!("Transaction expired. It is guaranteed it will not be committed on chain.").into());
                    }
                    chain_timestamp_usecs = Some(state.timestamp_usecs);
                }
                WaitForTransactionResult::NotFound(error) => {
                    if let RestError::Api(aptos_error_response) = error {
                        if let Some(state) = aptos_error_response.state {
                            if expiration_timestamp_secs <= state.timestamp_usecs / 1_000_000 {
                                if reached_mempool {
                                    return Err(anyhow!("Transaction expired. It is guaranteed it will not be committed on chain.").into());
                                } else {
                                    // We want to know whether we ever got Pending state from the mempool,
                                    // to warn in case we didn't.
                                    // Unless we are calling endpoint that is a very large load-balanced pool of nodes,
                                    // we should always see pending after submitting a transaction.
                                    // (i.e. if we hit the node we submitted a transaction to,
                                    // it shouldn't return NotFound on the first call)
                                    //
                                    // At the end, when the expiration happens, we might get NotFound or Pending
                                    // based on whether GC run on the full node to remove expired transaction,
                                    // so that information is not useful. So we need to keep this variable as state.
                                    return Err(anyhow!("Transaction expired, without being seen in mempool. It is guaranteed it will not be committed on chain.").into());
                                }
                            }
                            chain_timestamp_usecs = Some(state.timestamp_usecs);
                        }
                    } else {
                        return Err(error);
                    }
                    sample!(
                        SampleRate::Duration(Duration::from_secs(30)),
                        debug!(
                            "Cannot yet find transaction in mempool on {:?}, continuing to wait.",
                            self.path_prefix_string(),
                        )
                    );
                }
            }

            if let Some(max_server_lag_wait_duration) = max_server_lag_wait {
                if aptos_infallible::duration_since_epoch().as_secs()
                    > expiration_timestamp_secs + max_server_lag_wait_duration.as_secs()
                {
                    return Err(anyhow!(
                        "Ledger on endpoint ({}) is more than {}s behind current time, timing out waiting for the transaction. Warning, transaction ({}) might still succeed.",
                        self.path_prefix_string(),
                        max_server_lag_wait_duration.as_secs(),
                        hash,
                    ).into());
                }
            }

            let elapsed = start.elapsed();
            if let Some(timeout_duration) = timeout_from_call {
                if elapsed > timeout_duration {
                    return Err(anyhow!(
                        "Timeout of {}s after calling wait_for_transaction reached. Warning, transaction ({}) might still succeed.",
                        timeout_duration.as_secs(),
                        hash,
                    ).into());
                }
            }

            if elapsed.as_secs() > 30 {
                sample!(
                    SampleRate::Duration(Duration::from_secs(30)),
                    debug!(
                        "Continuing to wait for transaction {}, ledger on endpoint ({}) is {}",
                        hash,
                        self.path_prefix_string(),
                        if let Some(timestamp_usecs) = chain_timestamp_usecs {
                            format!(
                                "{}s behind current time",
                                aptos_infallible::duration_since_epoch()
                                    .saturating_sub(Duration::from_micros(timestamp_usecs))
                                    .as_secs()
                            )
                        } else {
                            "unreachable".to_string()
                        },
                    )
                );
            }

            tokio::time::sleep(DEFAULT_DELAY).await;
        }
    }

    pub async fn wait_for_transaction_by_hash(
        &self,
        hash: HashValue,
        expiration_timestamp_secs: u64,
        max_server_lag_wait: Option<Duration>,
        timeout_from_call: Option<Duration>,
    ) -> AptosResult<Response<Transaction>> {
        self.wait_for_transaction_by_hash_inner(
            hash,
            expiration_timestamp_secs,
            max_server_lag_wait,
            timeout_from_call,
            |hash| async move {
                let resp = self.get_transaction_by_hash_inner(hash).await?;
                if resp.status() != StatusCode::NOT_FOUND {
                    let txn_resp: Response<Transaction> = self.json(resp).await?;
                    let (transaction, state) = txn_resp.into_parts();

                    if !transaction.is_pending() {
                        if !transaction.success() {
                            Ok(WaitForTransactionResult::FailedExecution(
                                transaction.vm_status(),
                            ))
                        } else {
                            Ok(WaitForTransactionResult::Success(Response::new(
                                transaction,
                                state,
                            )))
                        }
                    } else {
                        Ok(WaitForTransactionResult::Pending(state))
                    }
                } else {
                    let error_response = parse_error(resp).await;
                    Ok(WaitForTransactionResult::NotFound(error_response))
                }
            },
        )
        .await
    }

    pub async fn wait_for_transaction_by_hash_bcs(
        &self,
        hash: HashValue,
        expiration_timestamp_secs: u64,
        max_server_lag_wait: Option<Duration>,
        timeout_from_call: Option<Duration>,
    ) -> AptosResult<Response<TransactionOnChainData>> {
        self.wait_for_transaction_by_hash_inner(
            hash,
            expiration_timestamp_secs,
            max_server_lag_wait,
            timeout_from_call,
            |hash| async move {
                let resp = self.get_transaction_by_hash_bcs_inner(hash).await?;
                if resp.status() != StatusCode::NOT_FOUND {
                    let resp = self.check_and_parse_bcs_response(resp).await?;
                    let resp = resp.and_then(|bytes| bcs::from_bytes(&bytes))?;
                    let (maybe_pending_txn, state) = resp.into_parts();

                    // If we have a committed transaction, determine if it failed or not
                    if let TransactionData::OnChain(txn) = maybe_pending_txn {
                        let status = txn.info.status();

                        if status.is_success() {
                            Ok(WaitForTransactionResult::Success(Response::new(txn, state)))
                        } else {
                            Ok(WaitForTransactionResult::FailedExecution(format!(
                                "{:?}",
                                status
                            )))
                        }
                    } else {
                        Ok(WaitForTransactionResult::Pending(state))
                    }
                } else {
                    let error_response = parse_error(resp).await;
                    Ok(WaitForTransactionResult::NotFound(error_response))
                }
            },
        )
        .await
    }

    pub async fn wait_for_version(&self, version: u64) -> Result<State> {
        const DEFAULT_TIMEOUT: Duration = Duration::from_secs(60);
        const DEFAULT_DELAY: Duration = Duration::from_millis(500);

        let start = std::time::Instant::now();
        loop {
            let state = self.get_ledger_information().await?.into_inner();
            if state.version >= version {
                return Ok(state);
            }

            if start.elapsed() >= DEFAULT_TIMEOUT {
                return Err(anyhow!(
                    "timeout when waiting for version {}, only got to {}",
                    version,
                    state.version
                ));
            }

            tokio::time::sleep(DEFAULT_DELAY).await;
        }
    }

    pub async fn get_transactions(
        &self,
        start: Option<u64>,
        limit: Option<u16>,
    ) -> AptosResult<Response<Vec<Transaction>>> {
        let url = self.build_path("transactions")?;

        let mut request = self.inner.get(url);
        if let Some(start) = start {
            request = request.query(&[("start", start)])
        }

        if let Some(limit) = limit {
            request = request.query(&[("limit", limit)])
        }

        let response = request.send().await?;

        self.json(response).await
    }

    pub async fn get_transactions_bcs(
        &self,
        start: Option<u64>,
        limit: Option<u16>,
    ) -> AptosResult<Response<Vec<TransactionOnChainData>>> {
        let url = self.build_path("transactions")?;
        let response = self.get_bcs_with_page(url, start, limit).await?;
        Ok(response.and_then(|inner| bcs::from_bytes(&inner))?)
    }

    pub async fn get_transaction_by_hash(
        &self,
        hash: HashValue,
    ) -> AptosResult<Response<Transaction>> {
        self.json(self.get_transaction_by_hash_inner(hash).await?)
            .await
    }

    pub async fn get_transaction_by_hash_bcs(
        &self,
        hash: HashValue,
    ) -> AptosResult<Response<TransactionData>> {
        let response = self.get_transaction_by_hash_bcs_inner(hash).await?;
        let response = self.check_and_parse_bcs_response(response).await?;
        Ok(response.and_then(|inner| bcs::from_bytes(&inner))?)
    }

    pub async fn get_transaction_by_hash_bcs_inner(
        &self,
        hash: HashValue,
    ) -> AptosResult<reqwest::Response> {
        let url = self.build_path(&format!("transactions/by_hash/{}", hash.to_hex_literal()))?;
        let response = self.inner.get(url).header(ACCEPT, BCS).send().await?;
        Ok(response)
    }

    async fn get_transaction_by_hash_inner(
        &self,
        hash: HashValue,
    ) -> AptosResult<reqwest::Response> {
        let url = self.build_path(&format!("transactions/by_hash/{}", hash.to_hex_literal()))?;
        Ok(self.inner.get(url).send().await?)
    }

    pub async fn get_transaction_by_version(
        &self,
        version: u64,
    ) -> AptosResult<Response<Transaction>> {
        self.json(self.get_transaction_by_version_inner(version).await?)
            .await
    }

    pub async fn get_transaction_by_version_bcs(
        &self,
        version: u64,
    ) -> AptosResult<Response<TransactionData>> {
        let url = self.build_path(&format!("transactions/by_version/{}", version))?;
        let response = self.get_bcs(url).await?;
        Ok(response.and_then(|inner| bcs::from_bytes(&inner))?)
    }

    async fn get_transaction_by_version_inner(
        &self,
        version: u64,
    ) -> AptosResult<reqwest::Response> {
        let url = self.build_path(&format!("transactions/by_version/{}", version))?;
        Ok(self.inner.get(url).send().await?)
    }

    pub async fn get_account_transactions(
        &self,
        address: AccountAddress,
        start: Option<u64>,
        limit: Option<u64>,
    ) -> AptosResult<Response<Vec<Transaction>>> {
        let url = self.build_path(&format!("accounts/{}/transactions", address))?;

        let mut request = self.inner.get(url);
        if let Some(start) = start {
            request = request.query(&[("start", start)])
        }

        if let Some(limit) = limit {
            request = request.query(&[("limit", limit)])
        }

        let response = request.send().await?;

        self.json(response).await
    }

    pub async fn get_account_transactions_bcs(
        &self,
        address: AccountAddress,
        start: Option<u64>,
        limit: Option<u16>,
    ) -> AptosResult<Response<Vec<TransactionOnChainData>>> {
        let url = self.build_path(&format!("accounts/{}/transactions", address))?;
        let response = self.get_bcs_with_page(url, start, limit).await?;
        Ok(response.and_then(|inner| bcs::from_bytes(&inner))?)
    }

    pub async fn get_account_resources(
        &self,
        address: AccountAddress,
    ) -> AptosResult<Response<Vec<Resource>>> {
        let url = self.build_path(&format!("accounts/{}/resources", address))?;

        let response = self.inner.get(url).send().await?;

        self.json(response).await
    }

    pub async fn get_account_resources_bcs(
        &self,
        address: AccountAddress,
    ) -> AptosResult<Response<BTreeMap<StructTag, Vec<u8>>>> {
        let url = self.build_path(&format!("accounts/{}/resources", address))?;
        let response = self.get_bcs(url).await?;
        Ok(response.and_then(|inner| bcs::from_bytes(&inner))?)
    }

    pub async fn get_account_resources_at_version(
        &self,
        address: AccountAddress,
        version: u64,
    ) -> AptosResult<Response<Vec<Resource>>> {
        let url = self.build_path(&format!(
            "accounts/{}/resources?ledger_version={}",
            address, version
        ))?;

        let response = self.inner.get(url).send().await?;

        self.json(response).await
    }

    pub async fn get_account_resources_at_version_bcs(
        &self,
        address: AccountAddress,
        version: u64,
    ) -> AptosResult<Response<BTreeMap<StructTag, Vec<u8>>>> {
        let url = self.build_path(&format!(
            "accounts/{}/resources?ledger_version={}",
            address, version
        ))?;
        let response = self.get_bcs(url).await?;
        Ok(response.and_then(|inner| bcs::from_bytes(&inner))?)
    }

    pub async fn get_resource<T: DeserializeOwned>(
        &self,
        address: AccountAddress,
        resource_type: &str,
    ) -> AptosResult<Response<T>> {
        let resp = self.get_account_resource(address, resource_type).await?;
        resp.and_then(|conf| {
            if let Some(res) = conf {
                serde_json::from_value(res.data)
                    .map_err(|e| anyhow!("deserialize {} failed: {}", resource_type, e).into())
            } else {
                Err(anyhow!(
                    "could not find resource {} in account {}",
                    resource_type,
                    address
                )
                .into())
            }
        })
    }

    pub async fn get_account_resource(
        &self,
        address: AccountAddress,
        resource_type: &str,
    ) -> AptosResult<Response<Option<Resource>>> {
        let url = self.build_path(&format!("accounts/{}/resource/{}", address, resource_type))?;

        let response = self
            .inner
            .get(url)
            .send()
            .await
            .map_err(anyhow::Error::from)?;
        self.json(response).await
    }

    pub async fn get_account_resource_bcs<T: DeserializeOwned>(
        &self,
        address: AccountAddress,
        resource_type: &str,
    ) -> AptosResult<Response<T>> {
        let url = self.build_path(&format!("accounts/{}/resource/{}", address, resource_type))?;
        let response = self.get_bcs(url).await?;
        Ok(response.and_then(|inner| bcs::from_bytes(&inner))?)
    }

    pub async fn get_account_resource_at_version_bcs<T: DeserializeOwned>(
        &self,
        address: AccountAddress,
        resource_type: &str,
        version: u64,
    ) -> AptosResult<Response<T>> {
        let url = self.build_path(&format!(
            "accounts/{}/resource/{}?ledger_version={}",
            address, resource_type, version
        ))?;

        let response = self.get_bcs(url).await?;
        Ok(response.and_then(|inner| bcs::from_bytes(&inner))?)
    }

    pub async fn get_account_resource_at_version_bytes(
        &self,
        address: AccountAddress,
        resource_type: &str,
        version: u64,
    ) -> AptosResult<Response<Vec<u8>>> {
        let url = self.build_path(&format!(
            "accounts/{}/resource/{}?ledger_version={}",
            address, resource_type, version
        ))?;

        let response = self.get_bcs(url).await?;
        Ok(response.map(|inner| inner.to_vec()))
    }

    pub async fn get_account_resource_at_version(
        &self,
        address: AccountAddress,
        resource_type: &str,
        version: u64,
    ) -> AptosResult<Response<Option<Resource>>> {
        let url = self.build_path(&format!(
            "accounts/{}/resource/{}?ledger_version={}",
            address, resource_type, version
        ))?;

        let response = self.inner.get(url).send().await?;
        self.json(response).await
    }

    pub async fn get_account_modules(
        &self,
        address: AccountAddress,
    ) -> AptosResult<Response<Vec<MoveModuleBytecode>>> {
        let url = self.build_path(&format!("accounts/{}/modules", address))?;

        let response = self.inner.get(url).send().await?;
        self.json(response).await
    }

    pub async fn get_account_modules_bcs(
        &self,
        address: AccountAddress,
    ) -> AptosResult<Response<BTreeMap<MoveModuleId, Vec<u8>>>> {
        let url = self.build_path(&format!("accounts/{}/modules", address))?;
        let response = self.get_bcs(url).await?;
        Ok(response.and_then(|inner| bcs::from_bytes(&inner))?)
    }

    pub async fn get_account_module(
        &self,
        address: AccountAddress,
        module_name: &str,
    ) -> AptosResult<Response<MoveModuleBytecode>> {
        let url = self.build_path(&format!("accounts/{}/module/{}", address, module_name))?;
        self.get(url).await
    }

    pub async fn get_account_module_bcs(
        &self,
        address: AccountAddress,
        module_name: &str,
    ) -> AptosResult<Response<bytes::Bytes>> {
        let url = self.build_path(&format!("accounts/{}/module/{}", address, module_name))?;
        self.get_bcs(url).await
    }

    pub async fn get_account_events(
        &self,
        address: AccountAddress,
        struct_tag: &str,
        field_name: &str,
        start: Option<u64>,
        limit: Option<u16>,
    ) -> AptosResult<Response<Vec<VersionedEvent>>> {
        let url = self.build_path(&format!(
            "accounts/{}/events/{}/{}",
            address.to_hex_literal(),
            struct_tag,
            field_name
        ))?;
        let mut request = self.inner.get(url);
        if let Some(start) = start {
            request = request.query(&[("start", start)])
        }

        if let Some(limit) = limit {
            request = request.query(&[("limit", limit)])
        }

        let response = request.send().await?;
        self.json(response).await
    }

    pub async fn get_account_events_bcs(
        &self,
        address: AccountAddress,
        struct_tag: &str,
        field_name: &str,
        start: Option<u64>,
        limit: Option<u16>,
    ) -> AptosResult<Response<Vec<EventWithVersion>>> {
        let url = self.build_path(&format!(
            "accounts/{}/events/{}/{}",
            address.to_hex_literal(),
            struct_tag,
            field_name
        ))?;

        let response = self.get_bcs_with_page(url, start, limit).await?;
        Ok(response.and_then(|inner| bcs::from_bytes(&inner))?)
    }

    pub async fn get_new_block_events_bcs(
        &self,
        start: Option<u64>,
        limit: Option<u16>,
    ) -> Result<Response<Vec<VersionedNewBlockEvent>>> {
        #[derive(Clone, Debug, Serialize, Deserialize)]
        pub struct NewBlockEventResponse {
            hash: String,
            #[serde(deserialize_with = "deserialize_from_string")]
            epoch: u64,
            #[serde(deserialize_with = "deserialize_from_string")]
            round: u64,
            #[serde(deserialize_with = "deserialize_from_string")]
            height: u64,
            #[serde(deserialize_with = "deserialize_from_prefixed_hex_string")]
            previous_block_votes_bitvec: HexEncodedBytes,
            proposer: String,
            failed_proposer_indices: Vec<String>,
            #[serde(deserialize_with = "deserialize_from_string")]
            time_microseconds: u64,
        }

        let response = self
            .get_account_events_bcs(
                CORE_CODE_ADDRESS,
                "0x1::block::BlockResource",
                "new_block_events",
                start,
                limit,
            )
            .await?;

        response.and_then(|events| {
            let new_events: Result<Vec<_>> = events
                .into_iter()
                .map(|event| {
                    let version = event.transaction_version;
                    let sequence_number = event.event.sequence_number();

                    Ok(VersionedNewBlockEvent {
                        event: bcs::from_bytes(event.event.event_data())?,
                        version,
                        sequence_number,
                    })
                })
                .collect();
            new_events
        })
    }

    pub async fn get_table_item<K: Serialize>(
        &self,
        table_handle: AccountAddress,
        key_type: &str,
        value_type: &str,
        key: K,
    ) -> AptosResult<Response<Value>> {
        let url = self.build_path(&format!("tables/{}/item", table_handle))?;
        let data = json!({
            "key_type": key_type,
            "value_type": value_type,
            "key": json!(key),
        });

        let response = self.inner.post(url).json(&data).send().await?;
        self.json(response).await
    }

    pub async fn get_table_item_bcs<K: Serialize, T: DeserializeOwned>(
        &self,
        table_handle: AccountAddress,
        key_type: &str,
        value_type: &str,
        key: K,
    ) -> AptosResult<Response<T>> {
        let url = self.build_path(&format!("tables/{}/item", table_handle))?;
        let data = json!({
            "key_type": key_type,
            "value_type": value_type,
            "key": json!(key),
        });

        let response = self.post_bcs(url, data).await?;
        Ok(response.and_then(|inner| bcs::from_bytes(&inner))?)
    }

    pub async fn get_raw_table_item(
        &self,
        table_handle: AccountAddress,
        key: &[u8],
        version: u64,
    ) -> AptosResult<Response<Vec<u8>>> {
        let url = self.build_path(&format!(
            "tables/{}/raw_item?ledger_version={}",
            table_handle, version
        ))?;
        let data = json!({
            "key": hex::encode(key),
        });

        let response = self.post_bcs(url, data).await?;
        Ok(response.map(|inner| inner.to_vec()))
    }

    pub async fn get_account(&self, address: AccountAddress) -> AptosResult<Response<Account>> {
        let url = self.build_path(&format!("accounts/{}", address))?;
        let response = self.inner.get(url).send().await?;
        self.json(response).await
    }

    pub async fn get_account_bcs(
        &self,
        address: AccountAddress,
    ) -> AptosResult<Response<AccountResource>> {
        let url = self.build_path(&format!("accounts/{}", address))?;
        let response = self.get_bcs(url).await?;
        Ok(response.and_then(|inner| bcs::from_bytes(&inner))?)
    }

    pub async fn estimate_gas_price(&self) -> AptosResult<Response<GasEstimation>> {
        let url = self.build_path("estimate_gas_price")?;
        let response = self.inner.get(url).send().await?;
        self.json(response).await
    }

    pub async fn set_failpoint(&self, name: String, actions: String) -> AptosResult<String> {
        let mut base = self.build_path("set_failpoint")?;
        let url = base
            .query_pairs_mut()
            .append_pair("name", &name)
            .append_pair("actions", &actions)
            .finish();
        let response = self.inner.get(url.clone()).send().await?;

        if !response.status().is_success() {
            Err(parse_error(response).await)
        } else {
            Ok(response
                .text()
                .await
                .map_err(|e| anyhow::anyhow!("To text failed: {:?}", e))?)
        }
    }

    async fn check_response(
        &self,
        response: reqwest::Response,
    ) -> AptosResult<(reqwest::Response, State)> {
        if !response.status().is_success() {
            Err(parse_error(response).await)
        } else {
            let state = parse_state(&response)?;

            Ok((response, state))
        }
    }

    async fn json<T: serde::de::DeserializeOwned>(
        &self,
        response: reqwest::Response,
    ) -> AptosResult<Response<T>> {
        let (response, state) = self.check_response(response).await?;
        let json = response.json().await.map_err(anyhow::Error::from)?;
        Ok(Response::new(json, state))
    }

    pub async fn health_check(&self, seconds: u64) -> AptosResult<()> {
        let url = self.build_path("-/healthy")?;
        let response = self
            .inner
            .get(url)
            .query(&[("duration_secs", seconds)])
            .send()
            .await?;

        if !response.status().is_success() {
            Err(parse_error(response).await)
        } else {
            Ok(())
        }
    }

    async fn get<T: DeserializeOwned>(&self, url: Url) -> AptosResult<Response<T>> {
        self.json(self.inner.get(url).send().await?).await
    }

    async fn get_bcs(&self, url: Url) -> AptosResult<Response<bytes::Bytes>> {
        let response = self.inner.get(url).header(ACCEPT, BCS).send().await?;
        self.check_and_parse_bcs_response(response).await
    }

    async fn post_bcs(
        &self,
        url: Url,
        data: serde_json::Value,
    ) -> AptosResult<Response<bytes::Bytes>> {
        let response = self
            .inner
            .post(url)
            .header(ACCEPT, BCS)
            .json(&data)
            .send()
            .await?;
        self.check_and_parse_bcs_response(response).await
    }

    async fn get_bcs_with_page(
        &self,
        url: Url,
        start: Option<u64>,
        limit: Option<u16>,
    ) -> AptosResult<Response<bytes::Bytes>> {
        let mut request = self.inner.get(url).header(ACCEPT, BCS);
        if let Some(start) = start {
            request = request.query(&[("start", start)])
        }

        if let Some(limit) = limit {
            request = request.query(&[("limit", limit)])
        }

        let response = request.send().await?;
        self.check_and_parse_bcs_response(response).await
    }

    async fn check_and_parse_bcs_response(
        &self,
        response: reqwest::Response,
    ) -> AptosResult<Response<bytes::Bytes>> {
        let (response, state) = self.check_response(response).await?;
        Ok(Response::new(response.bytes().await?, state))
    }

    pub async fn try_until_ok<F, Fut, RetryFun, T>(
        total_wait: Option<Duration>,
        initial_interval: Option<Duration>,
        should_retry: RetryFun,
        function: F,
    ) -> AptosResult<T>
    where
        F: Fn() -> Fut,
        RetryFun: Fn(StatusCode, Option<AptosError>) -> bool,
        Fut: Future<Output = AptosResult<T>>,
    {
        let total_wait = total_wait.unwrap_or(DEFAULT_MAX_WAIT_DURATION);
        let mut backoff = initial_interval.unwrap_or(DEFAULT_INTERVAL_DURATION);
        let mut result = Err(RestError::Unknown(anyhow!("Failed to run function")));
        let start = Instant::now();

        // TODO: Add jitter
        while start.elapsed() < total_wait {
            result = function().await;

            let retry = match &result {
                Ok(_) => break,
                Err(err) => match err {
                    RestError::Api(inner) => {
                        should_retry(inner.status_code, Some(inner.error.clone()))
                    }
                    RestError::Http(status_code, _e) => should_retry(*status_code, None),
                    RestError::Bcs(_)
                    | RestError::Json(_)
                    | RestError::Timeout(_)
                    | RestError::Unknown(_) => true,
                    RestError::UrlParse(_) => false,
                },
            };

            if !retry {
                break;
            }

            info!(
                "Failed to call API, retrying in {}ms: {:?}",
                backoff.as_millis(),
                result.as_ref().err().unwrap()
            );

            tokio::time::sleep(backoff).await;
            backoff = backoff.saturating_mul(2);
        }

        result
    }
}

pub fn retriable_with_404(status_code: StatusCode, aptos_error: Option<AptosError>) -> bool {
    retriable(status_code, aptos_error) | matches!(status_code, StatusCode::NOT_FOUND)
}

pub fn retriable(status_code: StatusCode, _aptos_error: Option<AptosError>) -> bool {
    matches!(
        status_code,
        StatusCode::TOO_MANY_REQUESTS
            | StatusCode::SERVICE_UNAVAILABLE
            | StatusCode::INTERNAL_SERVER_ERROR
            | StatusCode::GATEWAY_TIMEOUT
            | StatusCode::BAD_GATEWAY
            | StatusCode::INSUFFICIENT_STORAGE
    )
}

impl From<(ReqwestClient, Url)> for Client {
    fn from((inner, base_url): (ReqwestClient, Url)) -> Self {
        Client {
            inner,
            base_url,
            version_path_base: DEFAULT_VERSION_PATH_BASE.to_string(),
        }
    }
}

#[derive(Debug, Clone)]
pub struct VersionedNewBlockEvent {
    /// event
    pub event: NewBlockEvent,
    /// version
    pub version: u64,
    /// sequence number
    pub sequence_number: u64,
}

fn parse_state(response: &reqwest::Response) -> AptosResult<State> {
    Ok(State::from_headers(response.headers())?)
}

fn parse_state_optional(response: &reqwest::Response) -> Option<State> {
    State::from_headers(response.headers())
        .map(Some)
        .unwrap_or(None)
}

async fn parse_error(response: reqwest::Response) -> RestError {
    let status_code = response.status();
    let maybe_state = parse_state_optional(&response);
    match response.json::<AptosError>().await {
        Ok(error) => (error, maybe_state, status_code).into(),
        Err(e) => RestError::Http(status_code, e),
    }
}

pub struct GasEstimationParams {
    pub estimated_gas_used: u64,
    pub estimated_gas_price: u64,
}

enum WaitForTransactionResult<T> {
    NotFound(RestError),
    FailedExecution(String),
    Pending(State),
    Success(Response<T>),
}

impl ExplainVMStatus for Client {
    // TODO: Add some caching
    fn get_module_bytecode(&self, module_id: &ModuleId) -> Result<Rc<dyn Bytecode>> {
        let bytes =
            block_on(self.get_account_module_bcs(*module_id.address(), module_id.name().as_str()))?
                .into_inner();

        let compiled_module = CompiledModule::deserialize(bytes.as_ref())?;
        Ok(Rc::new(compiled_module) as Rc<dyn Bytecode>)
    }
}


text:
package com.microsoft.azure.management.devtestlab;

import com.fasterxml.jackson.annotation.JsonProperty;

/**
 * Properties of a daily schedule.
 */
public class DayDetailsFragment {
    /**
     * The time of day the schedule will occur.
     */
    @JsonProperty(value = "time")
    private String time;

    /**
     * Get the time value.
     *
     * @return the time value
     */
    public String time() {
        return this.time;
    }

    /**
     * Set the time value.
     *
     * @param time the time value to set
     * @return the DayDetailsFragment object itself.
     */
    public DayDetailsFragment withTime(String time) {
        this.time = time;
        return this;
    }

}

redpajama_set_name: RedPajamaGithub


text:
from django import forms
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _

class LimitedMultipleChoiceField(forms.MultipleChoiceField):
    def __init__(self, *args, **kwargs):
        self.maximum_choices = kwargs.pop("maximum_choices")

        self.default_error_messages.update({
            "maximum_choices": _("You may select at most %(maximum)d choices (%(selected)d selected)")
        })

        super(LimitedMultipleChoiceField, self).__init__(*args, **kwargs)

    def validate(self, value):
        super(LimitedMultipleChoiceField, self).validate(value)

        selected_count = len(value)
        if self.maximum_choices and selected_count > self.maximum_choices:
            raise ValidationError(
                self.error_messages["maximum_choices"],
                code="maximum_choices",
                params={"maximum": self.maximum_choices, "selected": selected_count},
            )

class MultipleTextField(forms.MultiValueField):
    def __init__(self, fields_length, **kwargs):
        fields = tuple(forms.CharField(max_length=200) for _ in range(fields_length))
        kwargs.update({"fields": fields})
        super(MultipleTextField, self).__init__(**kwargs)
        self.fields_length = fields_length

    def compress(self, data_list):
        return data_list


text:
Address Book aplication created to save users address details to share address information when needed on internet.

Address, AddressTypes and Related Portal added.

Project architecture is a MEAN and its created with Yeoman meanjs-generator.

I will be host this project at heroku as soon as possible.


text:
                                                <?php echo CHtml::encode($this->pageTitle); ?>

Enter your new password

                                        <?php $this->renderPartial('application.views.widgets._alert') ?>
                                        <?php
                                        $form = $this->beginWidget('CActiveForm', array(
                                            'id' => 'admin-user-form',
                                            'enableClientValidation' => false,
                                            'focus' => array($model, 'password'),
                                            'clientOptions' => array(
                                                'validateOnSubmit' => false,
                                            ),
                                            'htmlOptions' => array(
                                                'class' => 'uk-form uk-width-medium-1-1',
                                            )
                                        ));
                                        ?>
                                        <?php echo $form->errorSummary($model, ''); ?>
                                        <fieldset>

                                                                <?php echo $form->passwordField($model, 'password', array('class' => 'form-control', 'placeholder' => $model->getAttributeLabel('password'))); ?>

                                                                <?php echo $form->passwordField($model, 'confirm', array('class' => 'form-control', 'placeholder' => $model->getAttributeLabel('confirm'))); ?>

                                                        <button type="submit" class="width-35 pull-right btn btn-sm btn-primary">Submit</button>

                                        </fieldset>
                                        <?php $this->endWidget(); ?>

<a href="<?php echo $this->createUrl('login') ?>" class="forgot-password-link">Cancel


text:
/**
 * Swaggy Jenkins
 * Jenkins API clients generated from Swagger / Open API specification
 *
 * The version of the OpenAPI document: 1.5.1-pre.0
 * Contact: blah@cliffano.com
 *
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

package org.openapitools.client;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Date;
import org.openapitools.client.model.*;

public class JsonUtil {
  public static GsonBuilder gsonBuilder;

  static {
    gsonBuilder = new GsonBuilder();
    gsonBuilder.serializeNulls();
    gsonBuilder.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
    gsonBuilder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
      public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        return new Date(json.getAsJsonPrimitive().getAsLong());
      }
    });
  }

  public static Gson getGson() {
    return gsonBuilder.create();
  }

  public static String serialize(Object obj){
    return getGson().toJson(obj);
  }

  public static <T> T deserializeToList(String jsonString, Class cls){
    return getGson().fromJson(jsonString, getListTypeForDeserialization(cls));
  }

  public static <T> T deserializeToObject(String jsonString, Class cls){
    return getGson().fromJson(jsonString, getTypeForDeserialization(cls));
  }

  public static Type getListTypeForDeserialization(Class cls) {
    String className = cls.getSimpleName();

    if ("AllView".equalsIgnoreCase(className)) {
      return new TypeToken<List<AllView>>(){}.getType();
    }

    if ("BranchImpl".equalsIgnoreCase(className)) {
      return new TypeToken<List<BranchImpl>>(){}.getType();
    }

    if ("BranchImpllinks".equalsIgnoreCase(className)) {
      return new TypeToken<List<BranchImpllinks>>(){}.getType();
    }

    if ("BranchImplpermissions".equalsIgnoreCase(className)) {
      return new TypeToken<List<BranchImplpermissions>>(){}.getType();
    }

    if ("CauseAction".equalsIgnoreCase(className)) {
      return new TypeToken<List<CauseAction>>(){}.getType();
    }

    if ("CauseUserIdCause".equalsIgnoreCase(className)) {
      return new TypeToken<List<CauseUserIdCause>>(){}.getType();
    }

    if ("ClassesByClass".equalsIgnoreCase(className)) {
      return new TypeToken<List<ClassesByClass>>(){}.getType();
    }

    if ("ClockDifference".equalsIgnoreCase(className)) {
      return new TypeToken<List<ClockDifference>>(){}.getType();
    }

    if ("ComputerSet".equalsIgnoreCase(className)) {
      return new TypeToken<List<ComputerSet>>(){}.getType();
    }

    if ("DefaultCrumbIssuer".equalsIgnoreCase(className)) {
      return new TypeToken<List<DefaultCrumbIssuer>>(){}.getType();
    }

    if ("DiskSpaceMonitorDescriptorDiskSpace".equalsIgnoreCase(className)) {
      return new TypeToken<List<DiskSpaceMonitorDescriptorDiskSpace>>(){}.getType();
    }

    if ("EmptyChangeLogSet".equalsIgnoreCase(className)) {
      return new TypeToken<List<EmptyChangeLogSet>>(){}.getType();
    }

    if ("ExtensionClassContainerImpl1".equalsIgnoreCase(className)) {
      return new TypeToken<List<ExtensionClassContainerImpl1>>(){}.getType();
    }

    if ("ExtensionClassContainerImpl1links".equalsIgnoreCase(className)) {
      return new TypeToken<List<ExtensionClassContainerImpl1links>>(){}.getType();
    }

    if ("ExtensionClassContainerImpl1map".equalsIgnoreCase(className)) {
      return new TypeToken<List<ExtensionClassContainerImpl1map>>(){}.getType();
    }

    if ("ExtensionClassImpl".equalsIgnoreCase(className)) {
      return new TypeToken<List<ExtensionClassImpl>>(){}.getType();
    }

    if ("ExtensionClassImpllinks".equalsIgnoreCase(className)) {
      return new TypeToken<List<ExtensionClassImpllinks>>(){}.getType();
    }

    if ("FavoriteImpl".equalsIgnoreCase(className)) {
      return new TypeToken<List<FavoriteImpl>>(){}.getType();
    }

    if ("FavoriteImpllinks".equalsIgnoreCase(className)) {
      return new TypeToken<List<FavoriteImpllinks>>(){}.getType();
    }

    if ("FreeStyleBuild".equalsIgnoreCase(className)) {
      return new TypeToken<List<FreeStyleBuild>>(){}.getType();
    }

    if ("FreeStyleProject".equalsIgnoreCase(className)) {
      return new TypeToken<List<FreeStyleProject>>(){}.getType();
    }

    if ("FreeStyleProjectactions".equalsIgnoreCase(className)) {
      return new TypeToken<List<FreeStyleProjectactions>>(){}.getType();
    }

    if ("FreeStyleProjecthealthReport".equalsIgnoreCase(className)) {
      return new TypeToken<List<FreeStyleProjecthealthReport>>(){}.getType();
    }

    if ("GenericResource".equalsIgnoreCase(className)) {
      return new TypeToken<List<GenericResource>>(){}.getType();
    }

    if ("GithubContent".equalsIgnoreCase(className)) {
      return new TypeToken<List<GithubContent>>(){}.getType();
    }

    if ("GithubFile".equalsIgnoreCase(className)) {
      return new TypeToken<List<GithubFile>>(){}.getType();
    }

    if ("GithubOrganization".equalsIgnoreCase(className)) {
      return new TypeToken<List<GithubOrganization>>(){}.getType();
    }

    if ("GithubOrganizationlinks".equalsIgnoreCase(className)) {
      return new TypeToken<List<GithubOrganizationlinks>>(){}.getType();
    }

    if ("GithubRepositories".equalsIgnoreCase(className)) {
      return new TypeToken<List<GithubRepositories>>(){}.getType();
    }

    if ("GithubRepositorieslinks".equalsIgnoreCase(className)) {
      return new TypeToken<List<GithubRepositorieslinks>>(){}.getType();
    }

    if ("GithubRepository".equalsIgnoreCase(className)) {
      return new TypeToken<List<GithubRepository>>(){}.getType();
    }

    if ("GithubRepositorylinks".equalsIgnoreCase(className)) {
      return new TypeToken<List<GithubRepositorylinks>>(){}.getType();
    }

    if ("GithubRepositorypermissions".equalsIgnoreCase(className)) {
      return new TypeToken<List<GithubRepositorypermissions>>(){}.getType();
    }

    if ("GithubRespositoryContainer".equalsIgnoreCase(className)) {
      return new TypeToken<List<GithubRespositoryContainer>>(){}.getType();
    }

    if ("GithubRespositoryContainerlinks".equalsIgnoreCase(className)) {
      return new TypeToken<List<GithubRespositoryContainerlinks>>(){}.getType();
    }

    if ("GithubScm".equalsIgnoreCase(className)) {
      return new TypeToken<List<GithubScm>>(){}.getType();
    }

    if ("GithubScmlinks".equalsIgnoreCase(className)) {
      return new TypeToken<List<GithubScmlinks>>(){}.getType();
    }

    if ("Hudson".equalsIgnoreCase(className)) {
      return new TypeToken<List<Hudson>>(){}.getType();
    }

    if ("HudsonMasterComputer".equalsIgnoreCase(className)) {
      return new TypeToken<List<HudsonMasterComputer>>(){}.getType();
    }

    if ("HudsonMasterComputerexecutors".equalsIgnoreCase(className)) {
      return new TypeToken<List<HudsonMasterComputerexecutors>>(){}.getType();
    }

    if ("HudsonMasterComputermonitorData".equalsIgnoreCase(className)) {
      return new TypeToken<List<HudsonMasterComputermonitorData>>(){}.getType();
    }

    if ("HudsonassignedLabels".equalsIgnoreCase(className)) {
      return new TypeToken<List<HudsonassignedLabels>>(){}.getType();
    }

    if ("InputStepImpl".equalsIgnoreCase(className)) {
      return new TypeToken<List<InputStepImpl>>(){}.getType();
    }

    if ("InputStepImpllinks".equalsIgnoreCase(className)) {
      return new TypeToken<List<InputStepImpllinks>>(){}.getType();
    }

    if ("Label1".equalsIgnoreCase(className)) {
      return new TypeToken<List<Label1>>(){}.getType();
    }

    if ("Link".equalsIgnoreCase(className)) {
      return new TypeToken<List<Link>>(){}.getType();
    }

    if ("ListView".equalsIgnoreCase(className)) {
      return new TypeToken<List<ListView>>(){}.getType();
    }

    if ("MultibranchPipeline".equalsIgnoreCase(className)) {
      return new TypeToken<List<MultibranchPipeline>>(){}.getType();
    }

    if ("NullSCM".equalsIgnoreCase(className)) {
      return new TypeToken<List<NullSCM>>(){}.getType();
    }

    if ("Organisation".equalsIgnoreCase(className)) {
      return new TypeToken<List<Organisation>>(){}.getType();
    }

    if ("Pipeline".equalsIgnoreCase(className)) {
      return new TypeToken<List<Pipeline>>(){}.getType();
    }

    if ("PipelineActivity".equalsIgnoreCase(className)) {
      return new TypeToken<List<PipelineActivity>>(){}.getType();
    }

    if ("PipelineActivityartifacts".equalsIgnoreCase(className)) {
      return new TypeToken<List<PipelineActivityartifacts>>(){}.getType();
    }

    if ("PipelineBranchesitem".equalsIgnoreCase(className)) {
      return new TypeToken<List<PipelineBranchesitem>>(){}.getType();
    }

    if ("PipelineBranchesitemlatestRun".equalsIgnoreCase(className)) {
      return new TypeToken<List<PipelineBranchesitemlatestRun>>(){}.getType();
    }

    if ("PipelineBranchesitempullRequest".equalsIgnoreCase(className)) {
      return new TypeToken<List<PipelineBranchesitempullRequest>>(){}.getType();
    }

    if ("PipelineBranchesitempullRequestlinks".equalsIgnoreCase(className)) {
      return new TypeToken<List<PipelineBranchesitempullRequestlinks>>(){}.getType();
    }

    if ("PipelineFolderImpl".equalsIgnoreCase(className)) {
      return new TypeToken<List<PipelineFolderImpl>>(){}.getType();
    }

    if ("PipelineImpl".equalsIgnoreCase(className)) {
      return new TypeToken<List<PipelineImpl>>(){}.getType();
    }

    if ("PipelineImpllinks".equalsIgnoreCase(className)) {
      return new TypeToken<List<PipelineImpllinks>>(){}.getType();
    }

    if ("PipelineRun".equalsIgnoreCase(className)) {
      return new TypeToken<List<PipelineRun>>(){}.getType();
    }

    if ("PipelineRunImpl".equalsIgnoreCase(className)) {
      return new TypeToken<List<PipelineRunImpl>>(){}.getType();
    }

    if ("PipelineRunImpllinks".equalsIgnoreCase(className)) {
      return new TypeToken<List<PipelineRunImpllinks>>(){}.getType();
    }

    if ("PipelineRunNode".equalsIgnoreCase(className)) {
      return new TypeToken<List<PipelineRunNode>>(){}.getType();
    }

    if ("PipelineRunNodeedges".equalsIgnoreCase(className)) {
      return new TypeToken<List<PipelineRunNodeedges>>(){}.getType();
    }

    if ("PipelineRunartifacts".equalsIgnoreCase(className)) {
      return new TypeToken<List<PipelineRunartifacts>>(){}.getType();
    }

    if ("PipelineStepImpl".equalsIgnoreCase(className)) {
      return new TypeToken<List<PipelineStepImpl>>(){}.getType();
    }

    if ("PipelineStepImpllinks".equalsIgnoreCase(className)) {
      return new TypeToken<List<PipelineStepImpllinks>>(){}.getType();
    }

    if ("PipelinelatestRun".equalsIgnoreCase(className)) {
      return new TypeToken<List<PipelinelatestRun>>(){}.getType();
    }

    if ("PipelinelatestRunartifacts".equalsIgnoreCase(className)) {
      return new TypeToken<List<PipelinelatestRunartifacts>>(){}.getType();
    }

    if ("Queue".equalsIgnoreCase(className)) {
      return new TypeToken<List<Queue>>(){}.getType();
    }

    if ("QueueBlockedItem".equalsIgnoreCase(className)) {
      return new TypeToken<List<QueueBlockedItem>>(){}.getType();
    }

    if ("QueueItemImpl".equalsIgnoreCase(className)) {
      return new TypeToken<List<QueueItemImpl>>(){}.getType();
    }

    if ("QueueLeftItem".equalsIgnoreCase(className)) {
      return new TypeToken<List<QueueLeftItem>>(){}.getType();
    }

    if ("ResponseTimeMonitorData".equalsIgnoreCase(className)) {
      return new TypeToken<List<ResponseTimeMonitorData>>(){}.getType();
    }

    if ("StringParameterDefinition".equalsIgnoreCase(className)) {
      return new TypeToken<List<StringParameterDefinition>>(){}.getType();
    }

    if ("StringParameterValue".equalsIgnoreCase(className)) {
      return new TypeToken<List<StringParameterValue>>(){}.getType();
    }

    if ("SwapSpaceMonitorMemoryUsage2".equalsIgnoreCase(className)) {
      return new TypeToken<List<SwapSpaceMonitorMemoryUsage2>>(){}.getType();
    }

    if ("UnlabeledLoadStatistics".equalsIgnoreCase(className)) {
      return new TypeToken<List<UnlabeledLoadStatistics>>(){}.getType();
    }

    if ("User".equalsIgnoreCase(className)) {
      return new TypeToken<List<User>>(){}.getType();
    }

    return new TypeToken<List<Object>>(){}.getType();
  }

  public static Type getTypeForDeserialization(Class cls) {
    String className = cls.getSimpleName();

    if ("AllView".equalsIgnoreCase(className)) {
      return new TypeToken<AllView>(){}.getType();
    }

    if ("BranchImpl".equalsIgnoreCase(className)) {
      return new TypeToken<BranchImpl>(){}.getType();
    }

    if ("BranchImpllinks".equalsIgnoreCase(className)) {
      return new TypeToken<BranchImpllinks>(){}.getType();
    }

    if ("BranchImplpermissions".equalsIgnoreCase(className)) {
      return new TypeToken<BranchImplpermissions>(){}.getType();
    }

    if ("CauseAction".equalsIgnoreCase(className)) {
      return new TypeToken<CauseAction>(){}.getType();
    }

    if ("CauseUserIdCause".equalsIgnoreCase(className)) {
      return new TypeToken<CauseUserIdCause>(){}.getType();
    }

    if ("ClassesByClass".equalsIgnoreCase(className)) {
      return new TypeToken<ClassesByClass>(){}.getType();
    }

    if ("ClockDifference".equalsIgnoreCase(className)) {
      return new TypeToken<ClockDifference>(){}.getType();
    }

    if ("ComputerSet".equalsIgnoreCase(className)) {
      return new TypeToken<ComputerSet>(){}.getType();
    }

    if ("DefaultCrumbIssuer".equalsIgnoreCase(className)) {
      return new TypeToken<DefaultCrumbIssuer>(){}.getType();
    }

    if ("DiskSpaceMonitorDescriptorDiskSpace".equalsIgnoreCase(className)) {
      return new TypeToken<DiskSpaceMonitorDescriptorDiskSpace>(){}.getType();
    }

    if ("EmptyChangeLogSet".equalsIgnoreCase(className)) {
      return new TypeToken<EmptyChangeLogSet>(){}.getType();
    }

    if ("ExtensionClassContainerImpl1".equalsIgnoreCase(className)) {
      return new TypeToken<ExtensionClassContainerImpl1>(){}.getType();
    }

    if ("ExtensionClassContainerImpl1links".equalsIgnoreCase(className)) {
      return new TypeToken<ExtensionClassContainerImpl1links>(){}.getType();
    }

    if ("ExtensionClassContainerImpl1map".equalsIgnoreCase(className)) {
      return new TypeToken<ExtensionClassContainerImpl1map>(){}.getType();
    }

    if ("ExtensionClassImpl".equalsIgnoreCase(className)) {
      return new TypeToken<ExtensionClassImpl>(){}.getType();
    }

    if ("ExtensionClassImpllinks".equalsIgnoreCase(className)) {
      return new TypeToken<ExtensionClassImpllinks>(){}.getType();
    }

    if ("FavoriteImpl".equalsIgnoreCase(className)) {
      return new TypeToken<FavoriteImpl>(){}.getType();
    }

    if ("FavoriteImpllinks".equalsIgnoreCase(className)) {
      return new TypeToken<FavoriteImpllinks>(){}.getType();
    }

    if ("FreeStyleBuild".equalsIgnoreCase(className)) {
      return new TypeToken<FreeStyleBuild>(){}.getType();
    }

    if ("FreeStyleProject".equalsIgnoreCase(className)) {
      return new TypeToken<FreeStyleProject>(){}.getType();
    }

    if ("FreeStyleProjectactions".equalsIgnoreCase(className)) {
      return new TypeToken<FreeStyleProjectactions>(){}.getType();
    }

    if ("FreeStyleProjecthealthReport".equalsIgnoreCase(className)) {
      return new TypeToken<FreeStyleProjecthealthReport>(){}.getType();
    }

    if ("GenericResource".equalsIgnoreCase(className)) {
      return new TypeToken<GenericResource>(){}.getType();
    }

    if ("GithubContent".equalsIgnoreCase(className)) {
      return new TypeToken<GithubContent>(){}.getType();
    }

    if ("GithubFile".equalsIgnoreCase(className)) {
      return new TypeToken<GithubFile>(){}.getType();
    }

    if ("GithubOrganization".equalsIgnoreCase(className)) {
      return new TypeToken<GithubOrganization>(){}.getType();
    }

    if ("GithubOrganizationlinks".equalsIgnoreCase(className)) {
      return new TypeToken<GithubOrganizationlinks>(){}.getType();
    }

    if ("GithubRepositories".equalsIgnoreCase(className)) {
      return new TypeToken<GithubRepositories>(){}.getType();
    }

    if ("GithubRepositorieslinks".equalsIgnoreCase(className)) {
      return new TypeToken<GithubRepositorieslinks>(){}.getType();
    }

    if ("GithubRepository".equalsIgnoreCase(className)) {
      return new TypeToken<GithubRepository>(){}.getType();
    }

    if ("GithubRepositorylinks".equalsIgnoreCase(className)) {
      return new TypeToken<GithubRepositorylinks>(){}.getType();
    }

    if ("GithubRepositorypermissions".equalsIgnoreCase(className)) {
      return new TypeToken<GithubRepositorypermissions>(){}.getType();
    }

    if ("GithubRespositoryContainer".equalsIgnoreCase(className)) {
      return new TypeToken<GithubRespositoryContainer>(){}.getType();
    }

    if ("GithubRespositoryContainerlinks".equalsIgnoreCase(className)) {
      return new TypeToken<GithubRespositoryContainerlinks>(){}.getType();
    }

    if ("GithubScm".equalsIgnoreCase(className)) {
      return new TypeToken<GithubScm>(){}.getType();
    }

    if ("GithubScmlinks".equalsIgnoreCase(className)) {
      return new TypeToken<GithubScmlinks>(){}.getType();
    }

    if ("Hudson".equalsIgnoreCase(className)) {
      return new TypeToken<Hudson>(){}.getType();
    }

    if ("HudsonMasterComputer".equalsIgnoreCase(className)) {
      return new TypeToken<HudsonMasterComputer>(){}.getType();
    }

    if ("HudsonMasterComputerexecutors".equalsIgnoreCase(className)) {
      return new TypeToken<HudsonMasterComputerexecutors>(){}.getType();
    }

    if ("HudsonMasterComputermonitorData".equalsIgnoreCase(className)) {
      return new TypeToken<HudsonMasterComputermonitorData>(){}.getType();
    }

    if ("HudsonassignedLabels".equalsIgnoreCase(className)) {
      return new TypeToken<HudsonassignedLabels>(){}.getType();
    }

    if ("InputStepImpl".equalsIgnoreCase(className)) {
      return new TypeToken<InputStepImpl>(){}.getType();
    }

    if ("InputStepImpllinks".equalsIgnoreCase(className)) {
      return new TypeToken<InputStepImpllinks>(){}.getType();
    }

    if ("Label1".equalsIgnoreCase(className)) {
      return new TypeToken<Label1>(){}.getType();
    }

    if ("Link".equalsIgnoreCase(className)) {
      return new TypeToken<Link>(){}.getType();
    }

    if ("ListView".equalsIgnoreCase(className)) {
      return new TypeToken<ListView>(){}.getType();
    }

    if ("MultibranchPipeline".equalsIgnoreCase(className)) {
      return new TypeToken<MultibranchPipeline>(){}.getType();
    }

    if ("NullSCM".equalsIgnoreCase(className)) {
      return new TypeToken<NullSCM>(){}.getType();
    }

    if ("Organisation".equalsIgnoreCase(className)) {
      return new TypeToken<Organisation>(){}.getType();
    }

    if ("Pipeline".equalsIgnoreCase(className)) {
      return new TypeToken<Pipeline>(){}.getType();
    }

    if ("PipelineActivity".equalsIgnoreCase(className)) {
      return new TypeToken<PipelineActivity>(){}.getType();
    }

    if ("PipelineActivityartifacts".equalsIgnoreCase(className)) {
      return new TypeToken<PipelineActivityartifacts>(){}.getType();
    }

    if ("PipelineBranchesitem".equalsIgnoreCase(className)) {
      return new TypeToken<PipelineBranchesitem>(){}.getType();
    }

    if ("PipelineBranchesitemlatestRun".equalsIgnoreCase(className)) {
      return new TypeToken<PipelineBranchesitemlatestRun>(){}.getType();
    }

    if ("PipelineBranchesitempullRequest".equalsIgnoreCase(className)) {
      return new TypeToken<PipelineBranchesitempullRequest>(){}.getType();
    }

    if ("PipelineBranchesitempullRequestlinks".equalsIgnoreCase(className)) {
      return new TypeToken<PipelineBranchesitempullRequestlinks>(){}.getType();
    }

    if ("PipelineFolderImpl".equalsIgnoreCase(className)) {
      return new TypeToken<PipelineFolderImpl>(){}.getType();
    }

    if ("PipelineImpl".equalsIgnoreCase(className)) {
      return new TypeToken<PipelineImpl>(){}.getType();
    }

    if ("PipelineImpllinks".equalsIgnoreCase(className)) {
      return new TypeToken<PipelineImpllinks>(){}.getType();
    }

    if ("PipelineRun".equalsIgnoreCase(className)) {
      return new TypeToken<PipelineRun>(){}.getType();
    }

    if ("PipelineRunImpl".equalsIgnoreCase(className)) {
      return new TypeToken<PipelineRunImpl>(){}.getType();
    }

    if ("PipelineRunImpllinks".equalsIgnoreCase(className)) {
      return new TypeToken<PipelineRunImpllinks>(){}.getType();
    }

    if ("PipelineRunNode".equalsIgnoreCase(className)) {
      return new TypeToken<PipelineRunNode>(){}.getType();
    }

    if ("PipelineRunNodeedges".equalsIgnoreCase(className)) {
      return new TypeToken<PipelineRunNodeedges>(){}.getType();
    }

    if ("PipelineRunartifacts".equalsIgnoreCase(className)) {
      return new TypeToken<PipelineRunartifacts>(){}.getType();
    }

    if ("PipelineStepImpl".equalsIgnoreCase(className)) {
      return new TypeToken<PipelineStepImpl>(){}.getType();
    }

    if ("PipelineStepImpllinks".equalsIgnoreCase(className)) {
      return new TypeToken<PipelineStepImpllinks>(){}.getType();
    }

    if ("PipelinelatestRun".equalsIgnoreCase(className)) {
      return new TypeToken<PipelinelatestRun>(){}.getType();
    }

    if ("PipelinelatestRunartifacts".equalsIgnoreCase(className)) {
      return new TypeToken<PipelinelatestRunartifacts>(){}.getType();
    }

    if ("Queue".equalsIgnoreCase(className)) {
      return new TypeToken<Queue>(){}.getType();
    }

    if ("QueueBlockedItem".equalsIgnoreCase(className)) {
      return new TypeToken<QueueBlockedItem>(){}.getType();
    }

    if ("QueueItemImpl".equalsIgnoreCase(className)) {
      return new TypeToken<QueueItemImpl>(){}.getType();
    }

    if ("QueueLeftItem".equalsIgnoreCase(className)) {
      return new TypeToken<QueueLeftItem>(){}.getType();
    }

    if ("ResponseTimeMonitorData".equalsIgnoreCase(className)) {
      return new TypeToken<ResponseTimeMonitorData>(){}.getType();
    }

    if ("StringParameterDefinition".equalsIgnoreCase(className)) {
      return new TypeToken<StringParameterDefinition>(){}.getType();
    }

    if ("StringParameterValue".equalsIgnoreCase(className)) {
      return new TypeToken<StringParameterValue>(){}.getType();
    }

    if ("SwapSpaceMonitorMemoryUsage2".equalsIgnoreCase(className)) {
      return new TypeToken<SwapSpaceMonitorMemoryUsage2>(){}.getType();
    }

    if ("UnlabeledLoadStatistics".equalsIgnoreCase(className)) {
      return new TypeToken<UnlabeledLoadStatistics>(){}.getType();
    }

    if ("User".equalsIgnoreCase(className)) {
      return new TypeToken<User>(){}.getType();
    }

    return new TypeToken<Object>(){}.getType();
  }

};


text:
/*\
title: $:/core/modules/utils/dom/modal.js
type: application/javascript
module-type: utils

Modal message mechanism

\*/
(function(){

/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";

var widget = require("$:/core/modules/widgets/widget.js");

var Modal = function(wiki) {
	this.wiki = wiki;
	this.modalCount = 0;
};

/*
Display a modal dialogue
	title: Title of tiddler to display
	options: see below
Options include:
	downloadLink: Text of a big download link to include
*/
Modal.prototype.display = function(title,options) {
	options = options || {};
	var self = this,
		refreshHandler,
		duration = $tw.utils.getAnimationDuration(),
		tiddler = this.wiki.getTiddler(title);
	// Don't do anything if the tiddler doesn't exist
	if(!tiddler) {
		return;
	}
	// Create the variables
	var variables = $tw.utils.extend({currentTiddler: title},options.variables);
	// Create the wrapper divs
	var wrapper = document.createElement("div"),
		modalBackdrop = document.createElement("div"),
		modalWrapper = document.createElement("div"),
		modalHeader = document.createElement("div"),
		headerTitle = document.createElement("h3"),
		modalBody = document.createElement("div"),
		modalLink = document.createElement("a"),
		modalFooter = document.createElement("div"),
		modalFooterHelp = document.createElement("span"),
		modalFooterButtons = document.createElement("span");
	// Up the modal count and adjust the body class
	this.modalCount++;
	this.adjustPageClass();
	// Add classes
	$tw.utils.addClass(wrapper,"tc-modal-wrapper");
	$tw.utils.addClass(modalBackdrop,"tc-modal-backdrop");
	$tw.utils.addClass(modalWrapper,"tc-modal");
	$tw.utils.addClass(modalHeader,"tc-modal-header");
	$tw.utils.addClass(modalBody,"tc-modal-body");
	$tw.utils.addClass(modalFooter,"tc-modal-footer");
	// Join them together
	wrapper.appendChild(modalBackdrop);
	wrapper.appendChild(modalWrapper);
	modalHeader.appendChild(headerTitle);
	modalWrapper.appendChild(modalHeader);
	modalWrapper.appendChild(modalBody);
	modalFooter.appendChild(modalFooterHelp);
	modalFooter.appendChild(modalFooterButtons);
	modalWrapper.appendChild(modalFooter);
	// Render the title of the message
	var headerWidgetNode = this.wiki.makeTranscludeWidget(title,{
		field: "subtitle",
		mode: "inline",
		children: [{
			type: "text",
			attributes: {
				text: {
					type: "string",
					value: title
		}}}],
		parentWidget: $tw.rootWidget,
		document: document,
		variables: variables
	});
	headerWidgetNode.render(headerTitle,null);
	// Render the body of the message
	var bodyWidgetNode = this.wiki.makeTranscludeWidget(title,{
		parentWidget: $tw.rootWidget,
		document: document,
		variables: variables
	});
	bodyWidgetNode.render(modalBody,null);
	// Setup the link if present
	if(options.downloadLink) {
		modalLink.href = options.downloadLink;
		modalLink.appendChild(document.createTextNode("Right-click to save changes"));
		modalBody.appendChild(modalLink);
	}
	// Render the footer of the message
	if(tiddler && tiddler.fields && tiddler.fields.help) {
		var link = document.createElement("a");
		link.setAttribute("href",tiddler.fields.help);
		link.setAttribute("target","_blank");
		link.setAttribute("rel","noopener noreferrer");
		link.appendChild(document.createTextNode("Help"));
		modalFooterHelp.appendChild(link);
		modalFooterHelp.style.float = "left";
	}
	var footerWidgetNode = this.wiki.makeTranscludeWidget(title,{
		field: "footer",
		mode: "inline",
		children: [{
			type: "button",
			attributes: {
				message: {
					type: "string",
					value: "tm-close-tiddler"
				}
			},
			children: [{
				type: "text",
				attributes: {
					text: {
						type: "string",
						value: $tw.language.getString("Buttons/Close/Caption")
			}}}
		]}],
		parentWidget: $tw.rootWidget,
		document: document,
		variables: variables
	});
	footerWidgetNode.render(modalFooterButtons,null);
	// Set up the refresh handler
	refreshHandler = function(changes) {
		headerWidgetNode.refresh(changes,modalHeader,null);
		bodyWidgetNode.refresh(changes,modalBody,null);
		footerWidgetNode.refresh(changes,modalFooterButtons,null);
	};
	this.wiki.addEventListener("change",refreshHandler);
	// Add the close event handler
	var closeHandler = function(event) {
		// Remove our refresh handler
		self.wiki.removeEventListener("change",refreshHandler);
		// Decrease the modal count and adjust the body class
		self.modalCount--;
		self.adjustPageClass();
		// Force layout and animate the modal message away
		$tw.utils.forceLayout(modalBackdrop);
		$tw.utils.forceLayout(modalWrapper);
		$tw.utils.setStyle(modalBackdrop,[
			{opacity: "0"}
		]);
		$tw.utils.setStyle(modalWrapper,[
			{transform: "translateY(" + window.innerHeight + "px)"}
		]);
		// Set up an event for the transition end
		window.setTimeout(function() {
			if(wrapper.parentNode) {
				// Remove the modal message from the DOM
				document.body.removeChild(wrapper);
			}
		},duration);
		// Don't let anyone else handle the tm-close-tiddler message
		return false;
	};
	headerWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
	bodyWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
	footerWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
	// Set the initial styles for the message
	$tw.utils.setStyle(modalBackdrop,[
		{opacity: "0"}
	]);
	$tw.utils.setStyle(modalWrapper,[
		{transformOrigin: "0% 0%"},
		{transform: "translateY(" + (-window.innerHeight) + "px)"}
	]);
	// Put the message into the document
	document.body.appendChild(wrapper);
	// Set up animation for the styles
	$tw.utils.setStyle(modalBackdrop,[
		{transition: "opacity " + duration + "ms ease-out"}
	]);
	$tw.utils.setStyle(modalWrapper,[
		{transition: $tw.utils.roundTripPropertyName("transform") + " " + duration + "ms ease-in-out"}
	]);
	// Force layout
	$tw.utils.forceLayout(modalBackdrop);
	$tw.utils.forceLayout(modalWrapper);
	// Set final animated styles
	$tw.utils.setStyle(modalBackdrop,[
		{opacity: "0.7"}
	]);
	$tw.utils.setStyle(modalWrapper,[
		{transform: "translateY(0px)"}
	]);
};

Modal.prototype.adjustPageClass = function() {
	if($tw.pageContainer) {
		$tw.utils.toggleClass($tw.pageContainer,"tc-modal-displayed",this.modalCount > 0);
	}
};

exports.Modal = Modal;

})();


text:
/********************************************************************************
 #                          OpenWebGlobe Version 1.x                            #
 #                              (c) 2010-2015 by                                #
 #           University of Applied Sciences Northwestern Switzerland            #
 #                     Institute of Geomatics Engineering                       #
 #                           martin.christen@fhnw.ch                            #
 ********************************************************************************
 *     Licensed under MIT License. Read the file LICENSE for more information   *
 *******************************************************************************/

goog.provide('owg.ogObject');

goog.require('owg.ObjectDefs');

//------------------------------------------------------------------------------
/** @ignore */
var _g_objects = [];  // array containing all OpenWebGlobe objects

//------------------------------------------------------------------------------
/** @description register object*/
/** @ignore */
function _RegisterObject(obj)
{
   _g_objects.push(obj);
}
//------------------------------------------------------------------------------
/** @description unregister object*/
/** @ignore */
function _UnregisterObject(objid)
{
   for (var i=0;i<_g_objects.length;i++)
   {
      if (_g_objects[i].id == objid)
      {
         _g_objects[i]._OnDestroy();
         _g_objects.splice(i,1);
         return;
      }
   }
}
//------------------------------------------------------------------------------
/** @description return number of objects*/
/** @ignore */
function _GetNumObjects()
{
   return _g_objects.length;
}
//------------------------------------------------------------------------------
/** @description return object at specified position (iterate)*/
/** @param {number} index */
/** @returns The object at specified index.
/** @ignore */
function _GetObjectAt(index)
{
   if (index<0 || index>_g_objects.length-1)
   {
      return null;
   }
   return _g_objects[index];
}
//------------------------------------------------------------------------------
/** @description return object with specified id*/
/** @param {number} id The object id */
/** @returns {null|ogObject} The object or null if not found.
/** @ignore */
function _GetObjectFromId(id)
{
   if (id == -1)
   {
      return null;
   }

   for (var i=0;i<_g_objects.length;i++)
   {
      if (_g_objects[i].id == id)
      {
         return _g_objects[i];
      }
   }

   return null;
}
//------------------------------------------------------------------------------
/** @description return object with specified name*/
/** @param {string} name The object name */
/** @returns {ogObject} The object or null if not found.
/** @ignore */
function _GetObjectByName(name)
{
   for (var i=0;i<_g_objects.length;i++)
   {
      if (_g_objects[i].name == name)
      {
         return _g_objects[i];
      }
   }

   return null;
}
//------------------------------------------------------------------------------
/**
 * @constructor
 * @description Base class for all OpenWebGlobe objects
 * @author Martin Christen, martin.christen@fhnw.ch
 */
function ogObject()
{
   /** @type {ogObject} */
   this.parent = null; // no parent
   /** @type {string} */
   this.name = "ogObject";
   /** @type {number} */
   this.type = OG_OBJECT_INVALID;
   /** @type {number} */
   this.id = -1;
   /** @type {number} */
   this.status = OG_OBJECT_READY;
   /** @type {?function(number)} */
   this.cbfReady = null;
   /** @type {?function(number)} */
   this.cbfFailed = null;
}

//------------------------------------------------------------------------------

ogObject.prototype._OnDestroy = function()
{
   // called when object is destroyed
}

//------------------------------------------------------------------------------

ogObject.prototype.SetId = function(id)
{
   this.id = id;
}

//------------------------------------------------------------------------------

ogObject.prototype.SetParent = function(parent)
{
   this.parent = parent;
}

//------------------------------------------------------------------------------

ogObject.prototype.RegisterObject = function()
{
   _RegisterObject(this);
}
//------------------------------------------------------------------------------
ogObject.prototype.UnregisterObject = function()
{
   _UnregisterObject(this.id);
}

//------------------------------------------------------------------------------

ogObject.prototype.ParseOptions = function(options)
{

}

//------------------------------------------------------------------------------


text:
require 'tempfile'

FactoryGirl.define do

  factory :raw_config, class: String do
    trait :valid do
      initialize_with{ new <<-CONFIG }
# sample config file for log2mail
# comments start with '#'
# see source code doc/Configuration for additional information

defaults
  sendtime   = 20
  resendtime = 50
  maxlines   = 7
  template   = /tmp/mail_template
  fromaddr   = log2mail
  sendmail   = /usr/sbin/sendmail -oi -t
  mailto     = global_default_recipient@example.org  # new in log2mail.rb
file = test.log
  pattern = /any/
  pattern = string match
    mailto = special@recipient
      maxlines = 99
      CONFIG
    end

    trait :valid_without_defaults do
      initialize_with{ new <<-CONFIG }
file = test.log
  pattern = /any/
  pattern = string match
    mailto = special@recipient
      CONFIG
    end

    trait :valid_global_mailto_attributes do
      initialize_with{ new <<-CONFIG }
defaults
  mailto   = recipient@test.itstrauss.eu
  fromaddr = log2mail
file = test.log
  pattern = string pattern
  pattern = /regexp pattern/
      CONFIG
    end

    trait :valid_global_pattern_attributes do
      initialize_with{ new <<-CONFIG }
defaults
  pattern = recipient@test.itstrauss.eu
  mailto  = special recipient for pattern
file = test.log
      CONFIG
    end

    factory :valid_raw_config, traits: [:valid]
    factory :valid_raw_config_without_defaults, traits: [:valid_without_defaults]
    factory :valid_raw_config_with_defaults_with_global_mailto_attributes, traits: [:valid_global_mailto_attributes]
    factory :valid_raw_config_with_defaults_with_global_pattern_attributes, traits: [:valid_global_pattern_attributes]
  end

  factory :config, class: Log2mail::Config::ConfigFileHandler do

    factory :valid_config do
      initialize_with do
        tmp = Tempfile.new('valid_config')
        tmp.write build(:valid_raw_config)
        tmp.close
        new(tmp.path)
      end
    end

    factory :valid_config_without_defaults do
      initialize_with do
        tmp = Tempfile.new('valid_config')
        tmp.write build(:valid_raw_config_without_defaults)
        tmp.close
        new(tmp.path)
      end
    end
    factory :valid_config_with_defaults_with_global_mailto_attributes do
      initialize_with do
        tmp = Tempfile.new('valid_config')
        tmp.write build(:valid_raw_config_with_defaults_with_global_mailto_attributes)
        tmp.close
        new(tmp.path)
      end
    end
    factory :valid_config_with_defaults_with_global_pattern_attributes do
      initialize_with do
        tmp = Tempfile.new('valid_config')
        tmp.write build(:valid_raw_config_with_defaults_with_global_pattern_attributes)
        tmp.close
        new(tmp.path)
      end
    end

  end

  factory :hit, class: Log2mail::Hit do
    matched_text "a line with string match in it\n"
    pattern 'string match'
    file 'test.log'
    initialize_with{ new(matched_text, pattern, file) }
  end

  factory :report, class: Log2mail::Report do
    recipients 'recipient@example.org'
    hit { build(:hit) }

    template do
      tmp = Tempfile.new('valid_config')
      tmp.write <<-TEMPLATE
From: %f
To: %t
Subject: matched your pattern: %m

Hello!

We have matched your pattern "%m" in "%F" %n times:

%l

Yours,
log2mail.
      TEMPLATE
      tmp.close
      tmp.path
    end

  end

  factory :file, class: Log2mail::File do
    initialize_with do
      tmp = Tempfile.new('file')
      tmp.write <<-FILE
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
      FILE
      tmp.close
      new( tmp.path, ['ut'] )
    end
  end

  sequence :snippet do |n|
    <<-TEXT
# this is file file#{n}
file = file#{n}
  pattern = for file#{n}
    mailto = for pattern for file#{n}
    TEXT
  end

  sequence :filename do |n|
    "config file #{n}"
  end

  factory :defaults_snippet, class: Log2mail::Config::ConfigFileSnippet do
    filename = '/config/defaults'
    snippet = <<-TEXT
# comment
defaults
mailto = global_default_recipient@example.org
    TEXT
    initialize_with do
      new(snippet, filename)
    end
  end

  factory :just_comments_snippet, class: Log2mail::Config::ConfigFileSnippet do
    filename = '/config/comments'
    snippet = <<-TEXT
# comment
# other comment
# even more important comment
    TEXT
    initialize_with do
      new(snippet, filename)
    end
  end

  factory :config_file_snippet, class: Log2mail::Config::ConfigFileSnippet do
    snippet
    filename
    initialize_with do
      new(snippet, filename)
    end

  end

end


text:
namespace DBWorld.MailClient
{
    /// <summary>
    /// 联系人格式 : displayname<username@host>
    /// </summary>
    public class MailContact
    {
        public int Id { get; set; }

        public string DisplayName { get; set; }

        public string UserName { get; set; }

        public string Host { get; set; }

    }
}