text:
extern crate url;
extern crate serde_json;

use std::collections::HashMap;
use std::sync::RwLock;
use utils::{get_temp_dir_path, error};
use std::path::Path;
use url::Url;
use messages::validation;
use std::fs;
use std::io::prelude::*;
use serde_json::Value;

use error::prelude::*;

pub static CONFIG_POOL_NAME: &'static str = "pool_name";
pub static CONFIG_PROTOCOL_TYPE: &'static str = "protocol_type";
pub static CONFIG_AGENCY_ENDPOINT: &'static str = "agency_endpoint";
pub static CONFIG_AGENCY_DID: &'static str = "agency_did";
pub static CONFIG_AGENCY_VERKEY: &'static str = "agency_verkey";
pub static CONFIG_REMOTE_TO_SDK_DID: &'static str = "remote_to_sdk_did";
pub static CONFIG_REMOTE_TO_SDK_VERKEY: &'static str = "remote_to_sdk_verkey";
pub static CONFIG_SDK_TO_REMOTE_DID: &'static str = "sdk_to_remote_did"; // functionally not used
pub static CONFIG_SDK_TO_REMOTE_VERKEY: &'static str = "sdk_to_remote_verkey";
pub static CONFIG_INSTITUTION_DID: &'static str = "institution_did";
pub static CONFIG_INSTITUTION_VERKEY: &'static str = "institution_verkey"; // functionally not used
pub static CONFIG_INSTITUTION_NAME: &'static str = "institution_name";
pub static CONFIG_INSTITUTION_LOGO_URL: &'static str = "institution_logo_url";
pub static CONFIG_ENABLE_TEST_MODE: &'static str = "enable_test_mode";
pub static CONFIG_GENESIS_PATH: &str = "genesis_path";
pub static CONFIG_LOG_CONFIG: &str = "log_config";
pub static CONFIG_LINK_SECRET_ALIAS: &str = "link_secret_alias";
pub static CONFIG_EXPORTED_WALLET_PATH: &str = "exported_wallet_path";
pub static CONFIG_WALLET_BACKUP_KEY: &str = "backup_key";
pub static CONFIG_WALLET_KEY: &str = "wallet_key";
pub static CONFIG_WALLET_NAME: &'static str = "wallet_name";
pub static CONFIG_WALLET_TYPE: &'static str = "wallet_type";
pub static CONFIG_WALLET_STORAGE_CONFIG: &'static str = "storage_config";
pub static CONFIG_WALLET_STORAGE_CREDS: &'static str = "storage_credentials";
pub static CONFIG_WALLET_HANDLE: &'static str = "wallet_handle";
pub static CONFIG_THREADPOOL_SIZE: &'static str = "threadpool_size";
pub static CONFIG_WALLET_KEY_DERIVATION: &'static str = "wallet_key_derivation";
pub static CONFIG_PROTOCOL_VERSION: &'static str = "protocol_version";
pub static CONFIG_PAYMENT_METHOD: &'static str = "payment_method";

pub static DEFAULT_PROTOCOL_VERSION: usize = 2;
pub static MAX_SUPPORTED_PROTOCOL_VERSION: usize = 2;
pub static UNINITIALIZED_WALLET_KEY: &str = "<KEY_IS_NOT_SET>";
pub static DEFAULT_GENESIS_PATH: &str = "genesis.txn";
pub static DEFAULT_EXPORTED_WALLET_PATH: &str = "wallet.txn";
pub static DEFAULT_WALLET_NAME: &str = "LIBVCX_SDK_WALLET";
pub static DEFAULT_POOL_NAME: &str = "pool1";
pub static DEFAULT_LINK_SECRET_ALIAS: &str = "main";
pub static DEFAULT_DEFAULT: &str = "default";
pub static DEFAULT_URL: &str = "http://127.0.0.1:8080";
pub static DEFAULT_DID: &str = "2hoqvcwupRTUNkXn6ArYzs";
pub static DEFAULT_VERKEY: &str = "FuN98eH2eZybECWkofW6A9BKJxxnTatBCopfUiNxo6ZB";
pub static DEFAULT_ENABLE_TEST_MODE: &str = "false";
pub static DEFAULT_WALLET_BACKUP_KEY: &str = "backup_wallet_key";
pub static DEFAULT_WALLET_KEY: &str = "8dvfYSt5d1taSd6yJdpjq4emkwsPDDLYxkNFysFD2cZY";
pub static DEFAULT_THREADPOOL_SIZE: usize = 8;
pub static MASK_VALUE: &str = "********";
pub static DEFAULT_WALLET_KEY_DERIVATION: &str = "RAW";
pub static DEFAULT_PAYMENT_PLUGIN: &str = "libnullpay.so";
pub static DEFAULT_PAYMENT_INIT_FUNCTION: &str = "nullpay_init";
pub static DEFAULT_PAYMENT_METHOD: &str = "null";
pub static DEFAULT_PROTOCOL_TYPE: &str = "1.0";
pub static MAX_THREADPOOL_SIZE: usize = 128;

lazy_static! {
    static ref SETTINGS: RwLock<HashMap<String, String>> = RwLock::new(HashMap::new());
}

trait ToString {
    fn to_string(&self) -> Self;
}

impl ToString for HashMap<String, String> {
    fn to_string(&self) -> Self {
        let mut v = self.clone();
        v.insert(CONFIG_WALLET_KEY.to_string(), "********".to_string());
        v
    }
}

pub fn set_defaults() -> u32 {
    trace!("set_defaults >>>");

    // if this fails the program should exit
    let mut settings = SETTINGS.write().unwrap();

    settings.insert(CONFIG_POOL_NAME.to_string(), DEFAULT_POOL_NAME.to_string());
    settings.insert(CONFIG_WALLET_NAME.to_string(), DEFAULT_WALLET_NAME.to_string());
    settings.insert(CONFIG_WALLET_TYPE.to_string(), DEFAULT_DEFAULT.to_string());
    settings.insert(CONFIG_AGENCY_ENDPOINT.to_string(), DEFAULT_URL.to_string());
    settings.insert(CONFIG_AGENCY_DID.to_string(), DEFAULT_DID.to_string());
    settings.insert(CONFIG_AGENCY_VERKEY.to_string(), DEFAULT_VERKEY.to_string());
    settings.insert(CONFIG_REMOTE_TO_SDK_DID.to_string(), DEFAULT_DID.to_string());
    settings.insert(CONFIG_REMOTE_TO_SDK_VERKEY.to_string(), DEFAULT_VERKEY.to_string());
    settings.insert(CONFIG_INSTITUTION_DID.to_string(), DEFAULT_DID.to_string());
    settings.insert(CONFIG_INSTITUTION_NAME.to_string(), DEFAULT_DEFAULT.to_string());
    settings.insert(CONFIG_INSTITUTION_LOGO_URL.to_string(), DEFAULT_URL.to_string());
    settings.insert(CONFIG_SDK_TO_REMOTE_DID.to_string(), DEFAULT_DID.to_string());
    settings.insert(CONFIG_SDK_TO_REMOTE_VERKEY.to_string(), DEFAULT_VERKEY.to_string());
    settings.insert(CONFIG_WALLET_KEY.to_string(), DEFAULT_WALLET_KEY.to_string());
    settings.insert(CONFIG_WALLET_KEY_DERIVATION.to_string(), DEFAULT_WALLET_KEY_DERIVATION.to_string());
    settings.insert(CONFIG_LINK_SECRET_ALIAS.to_string(), DEFAULT_LINK_SECRET_ALIAS.to_string());
    settings.insert(CONFIG_PROTOCOL_VERSION.to_string(), DEFAULT_PROTOCOL_VERSION.to_string());
    settings.insert(CONFIG_EXPORTED_WALLET_PATH.to_string(),
                    get_temp_dir_path(Some(DEFAULT_EXPORTED_WALLET_PATH)).to_str().unwrap_or("").to_string());
    settings.insert(CONFIG_WALLET_BACKUP_KEY.to_string(), DEFAULT_WALLET_BACKUP_KEY.to_string());
    settings.insert(CONFIG_THREADPOOL_SIZE.to_string(), DEFAULT_THREADPOOL_SIZE.to_string());
    settings.insert(CONFIG_PAYMENT_METHOD.to_string(), DEFAULT_PAYMENT_METHOD.to_string());

    error::SUCCESS.code_num
}

pub fn validate_config(config: &HashMap<String, String>) -> VcxResult<u32> {
    trace!("validate_config >>> config: {:?}", config);

    //Mandatory parameters
    if config.get(CONFIG_WALLET_KEY).is_none() {
        return Err(VcxError::from(VcxErrorKind::MissingWalletKey));
    }

    // If values are provided, validate they're in the correct format
    validate_optional_config_val(config.get(CONFIG_INSTITUTION_DID), VcxErrorKind::InvalidDid, validation::validate_did)?;
    validate_optional_config_val(config.get(CONFIG_INSTITUTION_VERKEY), VcxErrorKind::InvalidVerkey, validation::validate_verkey)?;

    validate_optional_config_val(config.get(CONFIG_AGENCY_DID), VcxErrorKind::InvalidDid, validation::validate_did)?;
    validate_optional_config_val(config.get(CONFIG_AGENCY_VERKEY), VcxErrorKind::InvalidVerkey, validation::validate_verkey)?;

    validate_optional_config_val(config.get(CONFIG_SDK_TO_REMOTE_DID), VcxErrorKind::InvalidDid, validation::validate_did)?;
    validate_optional_config_val(config.get(CONFIG_SDK_TO_REMOTE_VERKEY), VcxErrorKind::InvalidVerkey, validation::validate_verkey)?;

    validate_optional_config_val(config.get(CONFIG_REMOTE_TO_SDK_DID), VcxErrorKind::InvalidDid, validation::validate_did)?;
    validate_optional_config_val(config.get(CONFIG_REMOTE_TO_SDK_VERKEY), VcxErrorKind::InvalidVerkey, validation::validate_verkey)?;

    validate_optional_config_val(config.get(CONFIG_AGENCY_ENDPOINT), VcxErrorKind::InvalidUrl, Url::parse)?;
    validate_optional_config_val(config.get(CONFIG_INSTITUTION_LOGO_URL), VcxErrorKind::InvalidUrl, Url::parse)?;

    Ok(error::SUCCESS.code_num)
}

fn validate_wallet_key(key: &str) -> VcxResult<u32> {
    if key == UNINITIALIZED_WALLET_KEY { return Err(VcxError::from(VcxErrorKind::MissingWalletKey)); }
    Ok(error::SUCCESS.code_num)
}

fn validate_optional_config_val<F, S, E>(val: Option<&String>, err: VcxErrorKind, closure: F) -> VcxResult<u32>
    where F: Fn(&str) -> Result<S, E> {
    if val.is_none() { return Ok(error::SUCCESS.code_num); }

    closure(val.as_ref().ok_or(VcxError::from(VcxErrorKind::InvalidConfiguration))?)
        .or(Err(VcxError::from(err)))?;

    Ok(error::SUCCESS.code_num)
}

pub fn log_settings() {
    let settings = SETTINGS.read().unwrap();
    trace!("loaded settings: {:?}", settings.to_string());
}

pub fn test_indy_mode_enabled() -> bool {
    let config = SETTINGS.read().unwrap();

    match config.get(CONFIG_ENABLE_TEST_MODE) {
        None => false,
        Some(value) => if value == "true" { true } else { if value == "indy" { true } else { false } },
    }
}

pub fn get_threadpool_size() -> usize {
    let size = match get_config_value(CONFIG_THREADPOOL_SIZE) {
        Ok(x) => x.parse::<usize>().unwrap_or(DEFAULT_THREADPOOL_SIZE),
        Err(x) => DEFAULT_THREADPOOL_SIZE,
    };

    if size > MAX_THREADPOOL_SIZE {
        MAX_THREADPOOL_SIZE
    } else {
        size
    }
}

pub fn test_agency_mode_enabled() -> bool {
    let config = SETTINGS.read().unwrap();

    match config.get(CONFIG_ENABLE_TEST_MODE) {
        None => false,
        Some(value) => if value == "true" { true } else { if value == "agency" { true } else { false } },
    }
}

pub fn process_config_string(config: &str) -> VcxResult<u32> {
    trace!("process_config_string >>> config {}", config);

    let configuration: Value = serde_json::from_str(config)
        .map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidJson, format!("Cannot deserialize config: {}", err)))?;

    if let Value::Object(ref map) = configuration {
        for (key, value) in map {
            set_config_value(key, value.as_str().ok_or(VcxError::from(VcxErrorKind::InvalidJson))?);
        }
    }

    validate_config(
        &SETTINGS.read().or(Err(VcxError::from(VcxErrorKind::InvalidConfiguration)))?.clone()
    )
}

pub fn process_config_file(path: &str) -> VcxResult<u32> {
    trace!("process_config_file >>> path: {}", path);

    if !Path::new(path).is_file() {
        error!("Configuration path was invalid");
        Err(VcxError::from_msg(VcxErrorKind::InvalidConfiguration, "Cannot find config file"))
    } else {
        process_config_string(&read_config_file(path)?)
    }
}

pub fn get_protocol_version() -> usize {
    let protocol_version = match get_config_value(CONFIG_PROTOCOL_VERSION) {
        Ok(ver) => ver.parse::<usize>().unwrap_or_else(|err| {
            warn!("Can't parse value of protocol version from config ({}), use default one ({})", err, DEFAULT_PROTOCOL_VERSION);
            DEFAULT_PROTOCOL_VERSION
        }),
        Err(err) => {
            info!("Can't fetch protocol version from config ({}), use default one ({})", err, DEFAULT_PROTOCOL_VERSION);
            DEFAULT_PROTOCOL_VERSION
        }
    };
    if protocol_version > MAX_SUPPORTED_PROTOCOL_VERSION {
        error!("Protocol version from config {}, greater then maximal supported {}, use maximum one",
               protocol_version, MAX_SUPPORTED_PROTOCOL_VERSION);
        MAX_SUPPORTED_PROTOCOL_VERSION
    } else {
        protocol_version
    }
}

pub fn get_config_value(key: &str) -> VcxResult<String> {
    trace!("get_config_value >>> key: {}", key);

    SETTINGS
        .read()
        .or(Err(VcxError::from_msg(VcxErrorKind::InvalidConfiguration, "Cannot read settings")))?
        .get(key)
        .map(|v| v.to_string())
        .ok_or(VcxError::from_msg(VcxErrorKind::InvalidConfiguration, format!("Cannot read \"{}\" from settings", key)))
}

pub fn set_config_value(key: &str, value: &str) {
    trace!("set_config_value >>> key: {}, value: {}", key, value);
    SETTINGS
        .write().unwrap()
        .insert(key.to_string(), value.to_string());
}

pub fn get_wallet_config(wallet_name: &str, wallet_type: Option<&str>, storage_config: Option<&str>) -> String {
    let mut config = json!({
        "id": wallet_name,
        "storage_type": wallet_type
    });

    let storage_config = get_config_value(CONFIG_WALLET_STORAGE_CONFIG).ok();
    if let Some(_config) = storage_config { config["storage_config"] = serde_json::from_str(&_config).unwrap(); }

    config.to_string()
}

pub fn get_wallet_credentials(storage_creds: Option<&str>) -> String {
    let key = get_config_value(CONFIG_WALLET_KEY).unwrap_or(UNINITIALIZED_WALLET_KEY.to_string());
    let mut credentials = json!({"key": key});

    let key_derivation = get_config_value(CONFIG_WALLET_KEY_DERIVATION).ok();
    if let Some(_key) = key_derivation { credentials["key_derivation_method"] = json!(_key); }

    let storage_creds = get_config_value(CONFIG_WALLET_STORAGE_CREDS).ok();
    if let Some(_creds) = storage_creds { credentials["storage_credentials"] = serde_json::from_str(&_creds).unwrap(); }

    credentials.to_string()
}

pub fn validate_payment_method() -> VcxResult<()> {
    let config = SETTINGS.read().unwrap();
    if let Some(method) = config.get(CONFIG_PAYMENT_METHOD) {
        if !method.to_string().is_empty() {
            return Ok(());
        }
    }
    return Err(VcxError::from(VcxErrorKind::MissingPaymentMethod));
}

pub fn get_payment_method() -> String {
    let payment_method = get_config_value(CONFIG_PAYMENT_METHOD).unwrap_or(DEFAULT_PAYMENT_METHOD.to_string());

    payment_method
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum ProtocolTypes {
    #[serde(rename = "1.0")]
    V1,
    #[serde(rename = "2.0")]
    V2,
}

impl Default for ProtocolTypes {
    fn default() -> Self {
        ProtocolTypes::V1
    }
}

impl From<String> for ProtocolTypes {
    fn from(type_: String) -> Self {
        match type_.as_str() {
            "1.0" => ProtocolTypes::V1,
            "2.0" => ProtocolTypes::V2,
            type_ @ _ => {
                error!("Unknown protocol type: {:?}. Use default", type_);
                ProtocolTypes::default()
            }
        }
    }
}

impl ::std::string::ToString for ProtocolTypes {
    fn to_string(&self) -> String {
        match self {
            ProtocolTypes::V1 => "1.0".to_string(),
            ProtocolTypes::V2 => "2.0".to_string(),
        }
    }
}

pub fn get_protocol_type() -> ProtocolTypes {
    ProtocolTypes::from(get_config_value(CONFIG_PROTOCOL_TYPE).unwrap_or(DEFAULT_PROTOCOL_TYPE.to_string()))
}

pub fn write_config_to_file(config: &str, path_string: &str) -> VcxResult<()> {
    trace!("write_config_to_file >>> config: {}, path_string: {}", config, path_string);

    let mut file = fs::File::create(Path::new(path_string))
        .map_err(|err| VcxError::from_msg(VcxErrorKind::UnknownError, err))?;

    file.write_all(config.as_bytes())
        .map_err(|err| VcxError::from_msg(VcxErrorKind::UnknownError, err))?;

    Ok(())
}

pub fn read_config_file(path: &str) -> VcxResult<String> {
    trace!("read_config_file >>> path: {}", path);
    let mut file = fs::File::open(path)
        .map_err(|err| VcxError::from_msg(VcxErrorKind::UnknownError, err))?;
    let mut config = String::new();
    file.read_to_string(&mut config)
        .map_err(|err| VcxError::from_msg(VcxErrorKind::UnknownError, err))?;
    Ok(config)
}

pub fn remove_file_if_exists(filename: &str) {
    trace!("remove_file_if_exists >>> filename: {}", filename);
    if Path::new(filename).exists() {
        match fs::remove_file(filename) {
            Ok(t) => (),
            Err(e) => println!("Unable to remove file: {:?}", e)
        }
    }
}

pub fn clear_config() {
    trace!("clear_config >>>");
    let mut config = SETTINGS.write().unwrap();
    config.clear();
}

#[cfg(test)]
pub mod tests {
    use super::*;
    use utils::get_temp_dir_path;

    #[test]
    fn test_bad_path() {
        let path = "garbage.txt";
        assert_eq!(process_config_file(&path).unwrap_err().kind(), VcxErrorKind::InvalidConfiguration);
    }

    #[test]
    fn test_read_config_file() {
        let config_path_buf = get_temp_dir_path(Some("test_init.json"));
        let config_path = config_path_buf.to_str().unwrap();

        let content = json!({
            "pool_name" : "pool1",
            "config_name":"config1",
            "wallet_name":"test_read_config_file",
            "agency_did" : "72x8p4HubxzUK1dwxcc5FU",
            "remote_to_sdk_did" : "UJGjM6Cea2YVixjWwHN9wq",
            "sdk_to_remote_did" : "AB3JM851T4EQmhh8CdagSP",
            "sdk_to_remote_verkey" : "888MFrZjXDoi2Vc8Mm14Ys112tEZdDegBZZoembFEATE",
            "institution_name" : "evernym enterprise",
            "agency_verkey" : "91qMFrZjXDoi2Vc8Mm14Ys112tEZdDegBZZoembFEATE",
            "remote_to_sdk_verkey" : "91qMFrZjXDoi2Vc8Mm14Ys112tEZdDegBZZoembFEATE",
            "genesis_path":"/tmp/pool1.txn",
            "wallet_key":"key"
        }).to_string();
        write_config_to_file(&content, config_path).unwrap();

        assert_eq!(read_config_file(config_path).unwrap(), content);
    }

    #[test]
    fn test_process_file() {
        let config_path_buf = get_temp_dir_path(Some("test_init.json"));
        let config_path = config_path_buf.to_str().unwrap();

        let content = json!({
            "pool_name" : "pool1",
            "config_name":"config1",
            "wallet_name":"test_process_file",
            "agency_did" : "72x8p4HubxzUK1dwxcc5FU",
            "remote_to_sdk_did" : "UJGjM6Cea2YVixjWwHN9wq",
            "sdk_to_remote_did" : "AB3JM851T4EQmhh8CdagSP",
            "sdk_to_remote_verkey" : "888MFrZjXDoi2Vc8Mm14Ys112tEZdDegBZZoembFEATE",
            "institution_name" : "evernym enterprise",
            "agency_verkey" : "91qMFrZjXDoi2Vc8Mm14Ys112tEZdDegBZZoembFEATE",
            "remote_to_sdk_verkey" : "91qMFrZjXDoi2Vc8Mm14Ys112tEZdDegBZZoembFEATE",
            "genesis_path":"/tmp/pool1.txn",
            "wallet_key":"key"
        }).to_string();
        write_config_to_file(&content, config_path).unwrap();

        assert_eq!(process_config_file(config_path).unwrap(), error::SUCCESS.code_num);

        assert_eq!(get_config_value("institution_name").unwrap(), "evernym enterprise".to_string());
    }

    #[test]
    fn test_process_config_str() {
        let content = json!({
            "pool_name" : "pool1",
            "config_name":"config1",
            "wallet_name":"test_process_config_str",
            "agency_did" : "72x8p4HubxzUK1dwxcc5FU",
            "remote_to_sdk_did" : "UJGjM6Cea2YVixjWwHN9wq",
            "sdk_to_remote_did" : "AB3JM851T4EQmhh8CdagSP",
            "sdk_to_remote_verkey" : "888MFrZjXDoi2Vc8Mm14Ys112tEZdDegBZZoembFEATE",
            "institution_name" : "evernym enterprise",
            "agency_verkey" : "91qMFrZjXDoi2Vc8Mm14Ys112tEZdDegBZZoembFEATE",
            "remote_to_sdk_verkey" : "91qMFrZjXDoi2Vc8Mm14Ys112tEZdDegBZZoembFEATE",
            "genesis_path":"/tmp/pool1.txn",
            "wallet_key":"key"
        }).to_string();

        assert_eq!(process_config_string(&content).unwrap(), error::SUCCESS.code_num);
    }

    #[test]
    fn test_validate_config() {
        let content = json!({
            "pool_name" : "pool1",
            "config_name":"config1",
            "wallet_name":"test_validate_config",
            "agency_did" : "72x8p4HubxzUK1dwxcc5FU",
            "remote_to_sdk_did" : "UJGjM6Cea2YVixjWwHN9wq",
            "sdk_to_remote_did" : "AB3JM851T4EQmhh8CdagSP",
            "sdk_to_remote_verkey" : "888MFrZjXDoi2Vc8Mm14Ys112tEZdDegBZZoembFEATE",
            "institution_name" : "evernym enterprise",
            "agency_verkey" : "91qMFrZjXDoi2Vc8Mm14Ys112tEZdDegBZZoembFEATE",
            "remote_to_sdk_verkey" : "91qMFrZjXDoi2Vc8Mm14Ys112tEZdDegBZZoembFEATE",
            "genesis_path":"/tmp/pool1.txn",
            "wallet_key":"key",
            "institution_did": "44x8p4HubxzUK1dwxcc5FU",
            "institution_verkey": "444MFrZjXDoi2Vc8Mm14Ys112tEZdDegBZZoembFEATE",
        }).to_string();
        let config: HashMap<String, String> = serde_json::from_str(&content).unwrap();
        assert_eq!(validate_config(&config).unwrap(), error::SUCCESS.code_num);
    }

    #[test]
    fn test_validate_config_failures() {
        let invalid = "invalid";
        let valid_did = DEFAULT_DID;
        let valid_ver = DEFAULT_VERKEY;

        let mut config: HashMap<String, String> = HashMap::new();
        assert_eq!(validate_config(&config).unwrap_err().kind(), VcxErrorKind::MissingWalletKey);

        config.insert(CONFIG_WALLET_KEY.to_string(), "password".to_string());
        config.insert(CONFIG_INSTITUTION_DID.to_string(), invalid.to_string());
        assert_eq!(validate_config(&config).unwrap_err().kind(), VcxErrorKind::InvalidDid);
        config.drain();

        config.insert(CONFIG_WALLET_KEY.to_string(), "password".to_string());
        config.insert(CONFIG_INSTITUTION_VERKEY.to_string(), invalid.to_string());
        assert_eq!(validate_config(&config).unwrap_err().kind(), VcxErrorKind::InvalidVerkey);
        config.drain();

        config.insert(CONFIG_WALLET_KEY.to_string(), "password".to_string());
        config.insert(CONFIG_AGENCY_DID.to_string(), invalid.to_string());
        assert_eq!(validate_config(&config).unwrap_err().kind(), VcxErrorKind::InvalidDid);
        config.drain();

        config.insert(CONFIG_WALLET_KEY.to_string(), "password".to_string());
        config.insert(CONFIG_AGENCY_VERKEY.to_string(), invalid.to_string());
        assert_eq!(validate_config(&config).unwrap_err().kind(), VcxErrorKind::InvalidVerkey);
        config.drain();

        config.insert(CONFIG_WALLET_KEY.to_string(), "password".to_string());
        config.insert(CONFIG_SDK_TO_REMOTE_DID.to_string(), invalid.to_string());
        assert_eq!(validate_config(&config).unwrap_err().kind(), VcxErrorKind::InvalidDid);
        config.drain();

        config.insert(CONFIG_WALLET_KEY.to_string(), "password".to_string());
        config.insert(CONFIG_SDK_TO_REMOTE_VERKEY.to_string(), invalid.to_string());
        assert_eq!(validate_config(&config).unwrap_err().kind(), VcxErrorKind::InvalidVerkey);
        config.drain();

        config.insert(CONFIG_WALLET_KEY.to_string(), "password".to_string());
        config.insert(CONFIG_REMOTE_TO_SDK_DID.to_string(), invalid.to_string());
        assert_eq!(validate_config(&config).unwrap_err().kind(), VcxErrorKind::InvalidDid);
        config.drain();

        config.insert(CONFIG_WALLET_KEY.to_string(), "password".to_string());
        config.insert(CONFIG_SDK_TO_REMOTE_VERKEY.to_string(), invalid.to_string());
        assert_eq!(validate_config(&config).unwrap_err().kind(), VcxErrorKind::InvalidVerkey);
        config.drain();

        config.insert(CONFIG_WALLET_KEY.to_string(), "password".to_string());
        config.insert(CONFIG_INSTITUTION_LOGO_URL.to_string(), invalid.to_string());
        assert_eq!(validate_config(&config).unwrap_err().kind(), VcxErrorKind::InvalidUrl);
        config.drain();
    }

    #[test]
    fn test_validate_optional_config_val() {
        let closure = Url::parse;
        let mut config: HashMap<String, String> = HashMap::new();
        config.insert("valid".to_string(), DEFAULT_URL.to_string());
        config.insert("invalid".to_string(), "invalid_url".to_string());

        //Success
        assert_eq!(validate_optional_config_val(config.get("valid"), VcxErrorKind::InvalidUrl, closure).unwrap(),
                   error::SUCCESS.code_num);

        // Success with No config
        assert_eq!(validate_optional_config_val(config.get("unknown"), VcxErrorKind::InvalidUrl, closure).unwrap(),
                   error::SUCCESS.code_num);

        // Fail with failed fn call
        assert_eq!(validate_optional_config_val(config.get("invalid"),
                                                VcxErrorKind::InvalidUrl,
                                                closure).unwrap_err().kind(), VcxErrorKind::InvalidUrl);
    }

    #[test]
    fn test_get_and_set_values() {
        let key = "key1".to_string();
        let value1 = "value1".to_string();

        // Fails with invalid key
        assert_eq!(get_config_value(&key).unwrap_err().kind(), VcxErrorKind::InvalidConfiguration);

        set_config_value(&key, &value1);
        assert_eq!(get_config_value(&key).unwrap(), value1);
    }

    #[test]
    fn test_payment_plugin_validation() {
        clear_config();
        set_config_value(CONFIG_PAYMENT_METHOD, "null");
        assert_eq!(validate_payment_method().unwrap(), ());
    }

    #[test]
    fn test_payment_plugin_validation_empty_string() {
        clear_config();
        set_config_value(CONFIG_PAYMENT_METHOD, "");
        assert_eq!(validate_payment_method().unwrap_err().kind(), VcxErrorKind::MissingPaymentMethod);
    }

    #[test]
    fn test_payment_plugin_validation_missing_option() {
        clear_config();
        assert_eq!(validate_payment_method().unwrap_err().kind(), VcxErrorKind::MissingPaymentMethod);
    }

    #[test]
    fn test_clear_config() {
        let content = json!({
            "pool_name" : "pool1",
            "config_name":"config1",
            "wallet_name":"test_clear_config",
            "institution_name" : "evernym enterprise",
            "genesis_path":"/tmp/pool1.txn",
            "wallet_key":"key",
        }).to_string();

        assert_eq!(process_config_string(&content).unwrap(), error::SUCCESS.code_num);

        assert_eq!(get_config_value("pool_name").unwrap(), "pool1".to_string());
        assert_eq!(get_config_value("config_name").unwrap(), "config1".to_string());
        assert_eq!(get_config_value("wallet_name").unwrap(), "test_clear_config".to_string());
        assert_eq!(get_config_value("institution_name").unwrap(), "evernym enterprise".to_string());
        assert_eq!(get_config_value("genesis_path").unwrap(), "/tmp/pool1.txn".to_string());
        assert_eq!(get_config_value("wallet_key").unwrap(), "key".to_string());

        clear_config();

        // Fails after  config is cleared
        assert_eq!(get_config_value("pool_name").unwrap_err().kind(), VcxErrorKind::InvalidConfiguration);
        assert_eq!(get_config_value("config_name").unwrap_err().kind(), VcxErrorKind::InvalidConfiguration);
        assert_eq!(get_config_value("wallet_name").unwrap_err().kind(), VcxErrorKind::InvalidConfiguration);
        assert_eq!(get_config_value("institution_name").unwrap_err().kind(), VcxErrorKind::InvalidConfiguration);
        assert_eq!(get_config_value("genesis_path").unwrap_err().kind(), VcxErrorKind::InvalidConfiguration);
        assert_eq!(get_config_value("wallet_key").unwrap_err().kind(), VcxErrorKind::InvalidConfiguration);
    }
}


text:
Amir Kumar (10 augustus 1923 - 25 januari 1980) was een Indiaas hockeyer.

Kumar won met de Indiase ploeg zowel in 1948 als in 1956 de gouden medaille op de Olympische Zomerspelen.

Resultaten
 1948  Olympische Zomerspelen in Londen
 1956  Olympische Zomerspelen in Melbourne

Indiaas hockeyer
Indiaas olympisch kampioen

redpajama_set_name: RedPajamaWikipedia


The Brittany is a medium-sized, leggy, dual-purpose dog, equally suited for sport and companionship. According to AKC? Registration Statistics, it has surged in popularity in the last 50 years due to its talents as both a hunting and show dog. Originally called the Brittany Spaniel, it is now referred to simply as the Brittany, as its hunting style more closely resembles that of pointing breeds. Its dense, flat or wavy coat can be orange and white or liver and white in either clear or roan patterns.
Average size: 30 to 40 pounds and 17 ?_ to 20 ?_ inches at the shoulder.


One of the biggest mistakes that annuity buyers make is to fail to ask the right questions of the person selling the annuity. While you should expect an annuity agent to be knowledgeable about annuity products, they may not always present the information in way that addresses your specific concerns. It's their responsibility to match your needs with the right annuity product and then explain how it addresses your needs. But, it is your responsibility to fully understand your needs and equip yourself with some basic knowledge of how annuity products work and how they differ, so you can confirm the choice of products.
Don't be afraid to walk into a meeting with your annuity agent with a list of questions on a notepad and the expectation that you will have them all answered to your satisfaction. This is not only essential in order to get the information you need for your decision, it is an excellent test to determine how credible and forthcoming the agent is. Any hesitation in the answer, or attempt to deflect the question, should be considered as a red flag. Don't hesitate to let the agent know that you don't feel as though your question was answered.
What is your background and experience with annuities?
Annuities are complex products, and there are many different types of annuities all designed to work differently to meet a variety of financial needs. It truly requires a person with an in depth knowledge of annuity products and a fair amount of experience in matching annuity products with peoples' needs. Choosing annuity options such as investment accounts, guaranteed options, income options, etc., are crucially important decisions and most investors need professional guidance in making them.
Annuities are sold by many different types of financial professionals: bank reps, stockbrokers, life insurance agents, financial planners, all who might specialize in financial products other than annuities. It is important to work with someone who specializes in annuities, preferable someone who has obtained some professional designations such as a CFP or CLU.
How many annuity products do you offer?
Annuity reps who only offer one or two annuity brands aren't in a position to find the very best match for your financial needs. It would be important to work with someone who isn't limited to selling a proprietary product. Agents that offer a broad range of annuities from different providers can focus on finding the one that best meets your needs, and they are better positioned to find the most competitive product. Independent insurance brokers or financial advisors tend to contract with many annuity providers. It would be important to know that they work with the more highly rated providers.
How do you go about choosing the right annuity for me?
Annuity sales people will sell you a product that suits them – either because it's the only one they have to sell, or it pays them the best. A true financial professional, will spend as much time as is needed to fully assess your needs, preferences, concerns, and risk tolerance. They will want to know how your assets are currently allocated, your qualified plan contribution level, and your tax situation. Any annuity agent who doesn't want to uncover this information from you before recommending a product, is just an annuity sales person. Avoid them. If you find the right financial professional, you should be able to entrust him or her with your information and know that they can't properly make a recommendation without it.
Will you provide me with a complete breakdown of my expenses, including your commissions?
There are two things you are looking for with this question: How much will your annuity cost you now and over time, and how your agent gets compensated. First, if an agent is not willing or able to do this, then walk away. Secondly, you want to see the depth in which your agent is willing to go to fully explain all of your costs and how it will impact your investment over time. Annuity sales people try to avoid the expense confrontation, and they are uncomfortable explaining how they get paid. A financial professional won't hesitate, and will be able to provide you with a detailed explanation of the annuity costs and where the money comes from to compensate him.
If I have questions or concerns about my annuity, who will I contact?
Truth be told, if your annuity is issued by a top notch provider, with a solid customer service protocol, you're probably better off talking directly with customer service reps of the provider. But, what you want to hear from your annuity agent is that he or she is ready, able and willing to ensure that your needs are met. It is especially important to have an engaged and proactive agent to work with during the annuity application and transaction process. Also, if you require changes or access to funds, it's your annuity agent that should be able to light a fire under the provider to make sure you receive the most responsive service.
Don't worry, your annuity agent was well compensated. You probably didn't pay the commission out of your deposit or account value, as it is usually paid by the insurance company from other fees it receives from your annuity. Regardless, you can demand and expect that your annuity agent will be there to act on your behalf.
Annuities are popular among investors who want to add some predictability and stability to their investment portfolio. The guarantees included in annuities provide investors with a level of comfort that, whether than investing for savings accumulation or income security, they can expect a minimum level of performance. Still, there are many moving parts within annuities that investors need to understand so there are no surprises somewhere down the line.
The first thing you should expect when buying an annuity is to encounter a vast array of annuity products that differ in their features, options and expenses. It can be a paralyzing experience once you discover the sheer number of annuity products that are available. The recommended approach is to be fully certain of your own specific objectives, needs, concerns and risk tolerance. Armed with your financial profile, you can quickly narrow down your choices to the most suitable types of annuity products.
The next thing you should expect is a complete explanation of the product and full disclosure of all of its expenses. All of the features, options and expenses of annuities are detailed in the contract specifications or prospectuses that can be obtained prior to their purchase. These should be thoroughly studied and understood before any investment is made. Contract specifications and prospectuses can be obtained by requesting them over the phone or online from the annuity provider.
As you dissect the contract specifications booklet or prospectus, you can expect to uncover an array of charges and expenses that you might not expect. All annuities include insurance charges for covering the mortality costs, administrative expenses, and distribution costs. These are broken down individually and are expressed as an annual percentage of the annuity account balance. In some cases, there is a flat fee charged for administrative expenses, and some insurers include a flat annual contract fee of $30 to $50. If you plan on adding any additional options or guarantees you can expect to pay additional charges.
Variable annuities include an extra fee for investment management. This fee compensates the professional managers of your separate account portfolios and is based on the assets under management. It is expressed as a percent which is applied annually to your account balance. Depending on the type of account, the fee can range from .5% to 1.5%. Generally, the more actively managed the account is, the higher the management fee. If you have more than one separate account, say a bond account and a stock account, each will have a separate management fee.
Finally, you can expect to see surrender fees which are applied to withdrawals made in a given year that exceed 10% of the account value. The fees are applied based on a schedule, called the surrender period which can last from five to 15 years. Typically, the fee starts out high and then is reduced by a point each year until it reached zero, which coincides with the end of the surrender period. Different classes of variable annuities may or may not have surrender periods, however, they will generally make up those charges in other ways, such as a sales charge or higher annual mortality charges.
With some variable annuities, you can expect to find a sales charge, also referred to as a front-end sales load. These will vary depending on the type of variable annuity you buy.
For instance, a B-Share variable annuity has no sales charge, but instead has a schedule of surrender fees. A-Share annuities have a sales charge but not surrender period. Some types have neither a sales charge nor a surrender period, but, you could expect to pay higher annual mortality fees. So, look carefully, and compare all expenses.
You can also expect to receive a sales pitch from an eager sales rep. Even if you do your own product research online, when you request information or application for purchase, you are likely to receive a call from a sales rep. Whether you are approached as a result of an online inquiry, or you seek out an annuity specialist on your own, if you follow the prescribed steps above, you will be armed with the information, about yourself, and about the annuity product of your choice, so you will be in control. If you sense that the sales rep is leading you down the wrong road, you will be in position to ask the right questions and the sales rep will realize that you are in control.
Finally, you should expect superior customer service from your annuity provider. Annuities are serious, long term investments and are a commitment on the part of investors and life insurers alike. From the moment you commit your funds, you should expect a high level of communications that keep you informed of the status of your transaction. Your provider should have an actively managed care line with knowledgeable representatives who can answer any question you have. If you buy a variable annuity, your provider should provide you with at least quarterly updates on your accounts, and have the ability to help you manage transfers between accounts.
If you expect the best from your annuity provider, then you should probably work with the best companies – the ones that have an established record of performance and solid customer service. Generally, the most highly rated companies have the financial strength and stability to be able to invest the resources needed to operate a reliable and responsive customer service department. The best indication of this would be to see how well the annuity provider can meet your expectations from the beginning. See how they respond to your early requests for contract specifications and information, and how willing they are to answer all of your questions before trying to sell you something.
At first glance, it may seem that indexed annuities and mutual funds are the same, but they do have differences that need to be considered before any investment is made. Mutual funds are professionally managed pools of money that are taken from other investors. The mutual fund manager has the ability to use those funds and buy stocks or other investments that grow the funds. Mutual funds are strictly regulated by the Securities and Exchange Commission.
Anyone is able to invest or purchase stock in a mutual fund. That growth, depending on how it is invested can be taxes immediately. An investor might be able to secure a dividend payment every month or elect to have the dividend reinvested in the mutual fund. An investor would be able to purchase those funds through a retirement-like account such as a Roth IRA or IRA where that investment would be deferred until the withdrawal is made.
When investors enter into a contract for purchasing an indexed annuity in exchange for a future payment amount, they agree to future distribution that is yet to be determined by the market's performance. After the "accumulation" period occurs the "distribution phase" begins. This is where the insurance company who issued the annuity will make installment payments or a "lump sum" payment to the investor. Gains during the accumulations period are protected from taxation on a yearly basis up until the investor makes his first withdrawal, making this an exceptional favorite among many investors.
Since the rate of return for the investor relies on the performance of the index market, it is possible for the purchaser of the annuity to get less in return than what he may have paid into the annuity. In addition, index annuities are cashed out before maturity or a specified date then significant fees and penalties will apply. A mutual fund, purchased on its own as a standard investment would not be penalized the standard 10% early withdraw penalty. The investor is still obligated to pay taxes on the growth of that mutual fund investment.
When it comes to annuities, certain contract features of the indexed annuity may determine that the investment may or may not be registered with the SEC. Generally, for SEC registered securities, for example, the insurance company must provide a minimum rate of return for the investor. Of course this may not always be guaranteed due to the built in nature of predictable market fluctuations and the type of investment. To be sure most mutual funds with equity stock vested in them are regulated by the SEC. Nevertheless, index annuities provide a great option for investors who would like to diversify their portfolio and peg their earning directly to the performance of the market with a particular investment vehicle. In addition, with index annuities, there may also be ceilings, or the maximum rate of interest which can be earned by the investor.
Though both mutual funds and fixed annuities provide stable ways to grow their money, they may be used for different purposes. Index annuities are a great option for the long-term investor who would hedge a percentage of their future retirement income stream based on the market's historical trend for increased growth. In either case, the investor should read the prospectus and investigate the health of the fund or the company issuing the annuity.
As an investment product, annuities can meet a wide range of needs for investors of all stripes, but as is the case with any investment product, they may not be suitable for all investors. Investors need to weigh the pros and cons of any investment product in the context of their own particular needs and priorities. Only then can it be determined whether an investment is best suited, over any other alternative to any one type of investor.
The features and characteristics of annuities are unique enough to be able to evaluate them in light of most peoples' circumstances. Here, we consider the pros and cons of annuities for people who meet the basic criteria as a potential annuity investor: high tax bracket, concerned with market volatility, concerned with safety of principal, long term time horizon, sufficient liquidity in other investments or savings, and fully utilized qualified retirement plans.
The earnings in annuity accounts are given the same tax treatment as qualified retirement plans in that they are allowed to accumulate without being taxed currently. Although they will be taxed when they are withdrawn, earnings can compound more quickly during the accumulation phase of the annuity. Investors who pay taxes at the higher income tax rates will benefit more than those who are taxed at the lower rates.
Fixed annuity rates are determined by the issuing life insurer based on the returns they generate out of their own investment account. Because they invest in a range of fixed income securities, they have the ability to generate yields that are higher than current market interest rates. Historically, annuity rates have always been higher than the rates available on other fixed yield investments.
Most annuities offer some sort of initial rate guarantee for a period of time. While the rate guarantee will eventually expire, and, the new rates can potentially be adjusted downward, they can't fall below the minimum rate guarantee.
The primary objective of the life insurance company is to preserve capital. They accomplish this by investing their assets conservatively and constantly monitoring their liquid reserves to ensure that there is always enough capital to cover all of its obligations. Additionally, most of the states provide protection in the form of guaranty fund that will cover annuity deposits. The coverage varies from state to state and ranges from $100,000 to $500,000.
Annuities are meant to be long term investments, however, they do include a withdrawal provision that allows for access to account values. They limit the withdrawals to 10% of the account value during the surrender period, over which they will charge a surrender fee. At the end of the surrender period, which range between five and 12 years, the funds are accessible without limit.
Investors who are concerned with the possibility of outliving their income use annuities to secure an income for life. Essentially, annuities are insurance against the possibility of living to long.
Annuity withdrawals are taxed as ordinary income. This could be a disadvantage if you find yourself in a high tax bracket in retirement.
The IRS treats annuities similarly to qualified retirement plans, such as IRAs, in so far as early withdrawals are concerned. For any withdrawal made before the age of 59 ½, the IRS may levy a penalty of 10% of the withdrawal.
The withdrawal provision in annuities allows for access to funds, but if the withdrawal is made within the surrender period that exceeds 10% of the account value in a given year, a fee is charged. The fees are initially high, in the range of 6 to 12%, and then gradually drop each year of the surrender period until they disappear all together.
Annuities do have costs and expenses associated with them, and, in some instances, they can mount up pretty quickly. Because they are a form of insurance, there are mortality charges, and since they are issued as contracts, they do require some paper pushing that result in administrative fees. Fees are charged each year as a percent of the account value, ranging from .75% to 1.25%. Variable annuities have investment management fees, similar to those charged in mutual funds. These fees can range from .5% to 1.3% depending on the type of investments that are being managed.
For some annuity investors, the cons could possibly offset the pros to the extent in which they achieve no real advantage from investing in annuities. For example, if surrender fees are paid on withdrawals made during the surrender period, they could completely offset the advantages of tax deferral. Or, annuities held for a shorter period of time, may not allow the tax deferral of above market interest rates to accumulate to the point of offsetting the expenses of the contract.
For investors who can commit to a longer term time frame, from 12 to 20 years, the pros of annuities should always outweigh the cons, which is why it so important to evaluate annuities in light of your total financial situation. For the right investor, annuities can perform like no other investment.
Copyright FixedAnnuitiesProsAndCons.com. All rights reserved.


ACTION....BEAUTY....EMOTION....these are what we strive to capture with all of our sports shoots. We'll always be in the right spot, with the right gear, and the right technique to immortalize that special moment on film, on video, or broadcast it to the world over the internet.
Bars, Beam, Floor, Vault... we shoot them all to capture that new move, thrilling routine, and hug from the coach. We strive to always be in the right place, with the right equipment, to capture the once in a lifetime shot.
Ballet, Tap, Jazz, Acro or Ballroom....we've got all of your dance moves covered. From dress and makeup backstage, through the final curtain, we'll capture those beautiful photos, and stunning videos that they'll remember for a lifetime.
Preserve those moments for the yearbook, or offer parents the opportunity to bring home a special photo or video of a special day. We take care to treat every athlete's day like it's their last, being sure not to miss that one goal, hoop, lap, jump, hit, or pass.
Shooting ALL the horses in ALL the rings, for ALL of the event is what we do. Carriage, Pleasure, Hunter, Walk Trot...it's all there and it's ALL important to us. Capture the entire team and mounts back at the stalls in a great event portrait, too.
From tee to green, and everything in between. On course, behind the ropes, sponsor shots, pro-am, whatever your needs....we'll be there. From action shots to portrait keepsakes, our team will always capture that special moment.
Whether it's a tri-athalon, marathon, Spartan race, or a local 5k fun run....every race is unique. Our shooters have the experience and equipment to capture those images that embody the spirit of the event.
Backstroke, butterfly, diving, relays... whatever the event, we'll jump in with both feet! Catch those hard to get action shots for the banquet, or plan your team portraits, we'll work with you to meet all of your media needs.


One thing that is as constant as loud music from my neighbors downstairs on New Year's Eve is the many many predictions made about the coming year in just about every major field of study and entertainment by anybody with a magazine column, website, or blog. Who am I to ignore this seemingly required aspect of journalism?
Read on for my predictions for 2006 in which I put aside my brand favoritism and speculate on which companies will soar, which characters will be reinvented, and which consoles will land in homes around the world in time for New Year's Day 2007.
I've been saying for a while now that video game publishers should bypass retail outlets and sell their games direct to consumers, citing that by cutting out the retail middleman publishers can potentially earn higher profits and customers can buy games for less of a cost. Leave it to Capcom to put the idea into practice in a big way, offering up bundles of current-generation titles for cheap.
Capcom is currently offering holiday bundles of Mega Man, Viewtiful Joe, Devil May Cry, Resident Evil, and other popular titles for Nintendo GameCube, Sony PlayStation 2, Microsoft Xbox, and Nintendo Game Boy Advance. How about picking up Mega Man Anniversary Collection, Mega Man X8, and Mega Man X: Command Mission for $50? They'll even toss in a few strategy guides. At retail that kind of bundle would cost upwards of $150. It's a "while supplies last" holiday promotion, but the point is that it's being done. Keep up the good work, Capcom.
We're closing in on the end of 2005 which must mean it's time for the editors of the Advanced Media Network to choose their top ten games of the year. Over at AMN's Nintendo GameCube department we've made out picks, and after playing so many good (and bad) games this year it can be hard to narrow the list down to ten. Sometimes it can be hard to pad the list out to ten depending on the year's games, but luckily this year that wasn't an issue. Don't miss my picks for this year: ten games that are unsurprisingly Nintendo-centric, but still some of the best titles on which you can spend your time and money.
Last week's look at the lost e-Reader levels of Nintendo's Super Mario Advance 4 has a little footnote: PTB reader CaitSith2 has been kind enough to step forward and identify himself as the person who made the do-it-yourself dotcode printing possible for the Japanese levels. This site features the dotcode data for your printing and scanning use, and all without linking to that pesky ROM file that makes linking to the site an issue of questionable legality. Also don't miss the video files that show just how the whole thing is done.
There's nothing new on PTB today due to an unexpected trip to the hospital for some IV fluids, medication, and x-rays. Armed with new medication, I'm hoping that things return to normal tomorrow. Your assignment in my absence is to go play a video game and be prepared to discuss it tomorrow in class.
It's nearly an even three-way split between Castlevania, Metroid, and Kirby when it comes to desired compilation games. It's easy to see the popularity behind each series, but I still have to say I want a Wario Land collection. With only five games in the series (three for Game Boy / Color, one for Virtual Boy, and one for Game Boy Advance) it should be easy to slap most of those on a Game Boy Advance game pak. The Virtual Boy game would need some work to make a version playable on the GBA, but it'd be a nice bonus for those who have never played Virtual Boy Wario Land. It's one of the top three games in the series, I say.
With the 2005 holiday gift season drawing to a close it's time to take stock of just how much loot we all scored this December. Did you get all of the games you wanted as presents? Vote in the poll and share your stories of holiday acquisition. Feel free to brag a little, too.
Following up on that rumor from a few weeks ago about The Legend of Zelda: Twilight Princess being a showcase for the upcoming Nintendo Revolution comes this rumor that the game will be released when the new console hits stores and will take advantage of the new controller, allowing players to swing the remote controller to control Link's sword. Note how this rumor has come out at the end of the week just before Christmas, meaning that there's nobody at Nintendo to confirm or deny the rumor because they're all on holiday break. Let me just say that I do not want this rumor to be true.
It seems as though a lot of people have not been happy with the Nintendo GameCube, but I've been thrilled with it. It's Nintendo's best home console since the Super NES in my opinion. I actually own more GameCube games than I do games for any other Nintendo console. As the GameCube generation winds down I want Twilight Princess to be that one last grand finale. The GameCube deserves a legacy that doesn't involve limping along from mid-2005 to the end of 2006. If Nintendo wants to add Revolution swordplay to the game then I'd like to see it remain a surprise. Release Twilight Princess in April, let us all play through it and enjoy it, and then when the Revolution comes at the end of the year reveal "By the way, put Twilight Princess into the Revolution and see what happens. We think you'll like it." That way the GameCube gets a memorable send-off and the Revolution launches with a nice surprise that allows us to experience the game all over again from a different gameplay angle.
When Nintendo decided to re-release the primary Super Mario back catalog for the Game Boy Advance, the company decided to include small amounts of new content. The remake of Yoshi's Island, Super Mario Advance 3, was the first in the series to include actual new levels. Six of 'em, to be exact. Then Super Mario Advance 4 (the remake of Super Mario Bros. 3) came along and Nintendo created over two dozen new levels to insert into the game (note that these are not the lost levels of the original Super Mario Bros. 3).
However, instead of loading them into the game pak the company decided to release them in dribs and drabs for the soon-to-be failed e-Reader accessory. The e-Reader fizzled before Nintendo could release all of the levels, with less than a third of the developed content making it into the hands of fans. Now a group of game enthusiast hackers are working to rediscover and release these latest lost levels, restoring yet another piece of Nintendo history that has been swept under the rug.
Bill Amend is at it again with his Fox Trot comic strip. Today's strip explains the real reason so many children are begging for a Microsoft Xbox 360. Ten-year-old Jason Fox figures that even though he doesn't really want one, by asking for the Xbox 360 his parents won't be able to find one, so they'll shower him with plenty of other gifts in order to ease his "pain".
The hell of it is that he's probably right. The last time I was in Best Buy I overheard a conversation between a middle-age woman and a salesclerk. She asked for the Xbox 360 to give to her young son for Christmas and was told the store was sold out, but the clerk talked her into buying the original Xbox instead. She then asked for "the popular games" and walked away happy with a stack of what had to be eight or so games chosen by the salesclerk. Jason Fox is right. Playing parents is almost too easy.


The proliferation of touchscreen devices has made soft keyboards a routine part of life. However, ultra-small computing platforms like the Sony SmartWatch and Apple iPod Nano lack a means of text entry. This limits their potential, despite the fact they are capable computers. In this work, we present a soft keyboard interaction technique called ZoomBoard that enables text entry on ultra-small devices. Our approach uses iterative zooming to enlarge otherwise impossibly tiny keys to comfortable size. We based our design on a QWERTY layout, so that it is immediately familiar to users and leverages existing skill. As the ultimate test, we ran a text entry experiment on a keyboard measuring just 16 x 6mm – smaller than a US penny. After eight practice trials, users achieved an average of 9.3 words per minute, with accuracy comparable to a full-sized physical keyboard. This compares favorably to existing mobile text input methods.


See, getting raised in the States was all I knew, so I didn't really engulf myself in any type of hispanic culture. I was taught very little spanish, and actually had to re-take it in high school because I performed so poorly. To this day when someone comes up to me to speak spanish (which happens quite a lot especially now that I'm in New York) I freeze. Anything I've learned, disappears. I get nervous, because I'm SUPPOSED to speak it. People tell me I need to learn, and I look the part. But I don't feel it. At all.
Back to Colombia: My dad and I eventually took a cab up into Pamplona for my first time, as well as his first time. The whole way up I was a nervous wreck. I knew nothing about this place. We kept passing a wide variety of homes--some in one piece--some in twenty. Some with some roofs, some without. I never knew when the cab driver would pull over and just say, "We're here!"
My dad and I met a worker in the hospital & explained I was born here then adopted to someone (that's all we knew) and I was looking to find a little more information about my birth parents. He said he didn't really know of anywhere we he could check for paper records, but that there was actually a Bien Estar office in Pamplona. My dad and I got directions from him, and then continued on. We came to a place with Bien Estar written across the front of the building, so we knocked and went in. Unfortunately, we didn't think this was the right place. Why? Because there were children running around, and colorfully decorated walls. Turns out, this was the DAYCARE, Bien Estar.


Explore the 34+ collection of Free Printable Disney Princess Clipart images at GetDrawings. Choose any clipart that best suits your projects, presentations or other design work. Edit and share any of these stunning Free Printable Disney Princess Clipart pics.


Hanging a picture, decorative projects and repair jobs can require a variety of different hardware. Learn which one to use for each and every task.
The fastener aisle in the hardware store houses thousands of screws, nails, bolts, hooks and more. Don't let it scare you off. It's easy once you learn a few general rules of thumb, what the numbered sizes mean and how to determine what length you'll need.
The first thing to consider is the wall type. Most newer homes have drywall. For small picture frames 8" x 10" or smaller and weighing a few ounces, a simple nail driven into the wall at a slight upward angle will do the trick. No need to worry about catching a stud. For larger and heavier frames it starts getting more complicated. Keep in mind the weight of the object as many fasteners have weight ratings. In a perfect world, a stud would be in the exact place you want to hang a picture, but we know our tastes and sightlines don't match construction techniques. Enter wall anchors. The classic wall anchor is tapped into place through a pilot hole, then a screw is driven through it. In this image, the screw causes the anchor to expand and grip the drywall with fins and expand in the back, making an anchor truly an anchor.
A third common wall fastener is a toggle bolt. Like a classic wall anchor, it is inserted into a pilot hole. What makes it unique is the spring inside, which makes the fastener pop open once it reaches the cavity behind the wall and creates a grappling-hook effect.
Time and weather take their toll, which makes your choice of fasteners for exterior projects very important. Deck screws are ubiquitous when it comes to outdoor projects. They are specially coated to resist corrosion and come in a large range of sizes, most commonly from 1 1/4" to 3". They are also considerably less expensive than stainless steel screws and aren't prone to head stripping, as stainless steel sometimes can be.
Surprisingly, there are a wider variety of nails for exterior use than screws, whether it's for decking, fencing, siding, roofing or outdoor furniture. In this image, notice the twisted shank of a galvanized deck/fencing nail. This variety offers the increased holding strength of a screw with the value of a nail.
As their common name indicates, deck screws are clearly designed for use in deck construction, specifically for attaching deck boards, but their use extends well beyond to other projects such as outdoor furniture. For heavy-duty construction using large dimensional lumber (4x4s for example), such as deck support, pergolas, arbors, treehouses and wood swingsets, use lag screws. They come in galvanized or stainless.
Nails (and brads) are good for basic construction (building a box) and when adhesives are used. For outdoor applications, use stainless or galvanized brads or nails. Brads or finish nails are best for attaching trim and molding and for furniture assembly. They are identified by their smaller heads versus a prototypical nail. Why? The smaller heads are driven below a surface and can be concealed by wood filler.
Brad nails are very often used in pneumatic nailers and come bundled in clips rather than loose. A variety of sizes are available. For example, if a brad is labeled #18 x 1 1/4. The #18 is the thickness or gauge (the lower the number the thicker the brad). The 1 1/4 is the length in inches. In contrast, with nails, the higher the number, the thicker the nail. An example of a common size for nails would be 4d (thickness) x 1 1/2 (length).
Screws work best when forces will be applied in multiple directions such as against a joint, or if extra weight will be applied, such as a bookshelf. Use screws if you don't plan on using additional adhesives. If you are building a simple shelf or bookcase, you can use glue and nails, but you'll feel much more secure about it if it fastened with screws. The threads of a screw grip and "bite" into the wood to make a joint stronger and more secure.
When drilling pilot holes for screws, be sure to match the diameter of the shank and not the threads. The gauge (thickness) of screws are listed similar to brads (#7, #8), but are more like nails in that the higher the gauge, the thicker the screw.
Nuts and bolts work well for projects that may need to be disassembled at some point or heavy-duty applications. They provide tremendous holding power, as you can use mechanical force (a wrench) to tighten the nut. Unlike screws, a pilot hole for a bolt should match or be slightly larger than the diameter of the threads and, of course, be drilled completely through. Bolt sizes are listed by diameter and length in inches.
What's the Correct Length to Use for a Fastener?
It depends on the application, but when joining the faces of two boards, you'll want to drive the fastener at least halfway through the adjoining board, but not completely through it. This image shows two 3/4" boards with a 1 1/4"-long screw. At that length, the screw extends into the adjoining board by 1/2" (1 1/4 – 3/4 = 1/2). Brads and screws are commonly available in 1 1/4" sizes. If joining at a right angle, use a fastener that is at least twice the thickness as the material. For example, when joining two 3/4" boards at a right angle, use a nail or screw that's at least 1 1/2" long.


text:
Q: How to increase digitcount in Digital Gauge? I'm trying to use application that was developed using .NET.

*

*This application uses Dundas Gauges (third party included in my application).

*Application uses jscript.net. I'm trying to use Digital gauge.

The problem that I have:
The number count is limited to 5. In my case I have 6 digits to display. If I provide 5 digits it works, if I provide 6 digits .. instead of displaying those numbers I see 'ERROR'
My question:
How could I increase allowed digit count? I used this code:
var digitGauge : GaugeControl = GaugeControl( form.All( "digitGauge" ) );
digitGauge.Value = 123456;

Note: I was looking for property DigitCount for variable digitGauge .. but it does not exist.
Could someone help me and correct my code?
Thanks

A: I am taking off this question. I decided not to use this type of gauge

redpajama_set_name: RedPajamaStackExchange


text:
On books, dogs, the pursuit of astronomy and good coffee
Categories: Crime Fiction, Gay Fiction, Horror, M/M Romance, Mystery, Thriller
Publisher: DSP Publications Cover Artist: Aaron Anderson
Cayce was just about to put the paper aside when another article—and a familiar name in the byline—caught his eye. "Teenager Reported Missing," by Dave Newton. It wasn't so much the headline that got his attention but the picture of the young girl beneath it. Pretty. Long blonde hair. And disturbingly familiar.
Even though Fawcettville was a small town, the girl's name, Lucy Plant, didn't ring any bells. Perhaps Cayce had waited on her at the Elite, the diner where he worked. But still, no specific recollection came back. Cayce couldn't visualize the girl sitting at the counter, nor at one of the booths.
And yet she looked so familiar, as if she were someone Cayce was friends with, or even a relative.
Cayce scanned the story. The girl had been reported missing by her mother yesterday afternoon, just before the storm that had caused such a turn in Cayce's own life.
There were no clues. The girl, at least according to her mother, could not possibly have been a runaway. "Lucy's a good girl," Amy Plant had told Fawcettville police detective JT Simmons. "She wouldn't even go down the block to visit a friend without telling us first."
The last time anyone had seen Lucy Plant was when her mother looked outside the living room window. Lucy had been playing with her Barbie dolls on the front lawn.
Cayce closed his eyes. He remembered, suddenly, the storm coming, and not knowing where Luke was. He sympathized with the girl's mother and the panic she must have felt when she couldn't locate her daughter.
A ceiling fan. Beneath his closed lids, Cayce saw a ceiling fan. He didn't know why. He didn't own one himself, and the one in his parents' living room was an entirely different model from this one, which was white, with a plain globe. His parents' fan had four frosted-glass light fixtures and faux wood blades.
Cayce kept his eyes closed, watching the ceiling fan whirl, its blades blurring and becoming singular. There was something wrong with the fan. It didn't work quite right.
Cayce felt nauseated and opened his eyes. His face was glazed with sweat. His stomach churned, and he was afraid he would vomit. Why was seeing a ceiling fan so disturbing? Or was this some sort of aftershock, an effect of his accident?
Cayce didn't think so.
He glanced down at the face of Lucy Plant and sucked in some air. "Oh my God," he whispered, "she's dead."
Photograph by Madison Parker
Rick R. Reed is all about exploring the romantic entanglements of gay men in contemporary, realistic settings. While his stories often contain elements of suspense, mystery and the paranormal, his focus ultimately returns to the power of love. He is the author of dozens of published novels, novellas, and short stories. He is a three-time EPIC eBook Award winner (for Caregiver, Orientation and The Blue Moon Cafe). Raining Men and Caregiver have both won the Rainbow Award for gay fiction. Lambda Literary Review has called him, "a writer that doesn't disappoint." Rick lives in Seattle with his husband and a very spoiled Boston terrier. He is forever "at work on another novel."
Tour Stops:
Parker Williams
Decadent Delights
Full Moon Dreaming
BFD Book Blog
Andrew Q. Gordon
Regular Guys, Hot Romance
My Fiction Nook
Emotion in Motion
Fangirl Moments and My Two Cents
Scattered Thoughts & Rogue Words
Velvet Panic
Inked Rainbow Reads
Queer Town Abbey
Elin Gregory
Jade Crystal
Love Bytes
Amanda C. Stone
Fallen Angel Reviews
Wicked Faerie's Tales and Reviews
Cate Ashwood
Sinfully Sexy
3 Chicks After Dark
Wake Up Your Wild Side
Book Reviews and More by Kathy
Michael Mandrake
Havan Fellows
Iyana Jenna
Congratulations to Rick R Reed on his first story with DSP imprint :) Quite a powerful cover on this book, thank you for a chance to win one of your books
Mystery, action, chills, and thrills spiced with romance and desire. ELIZABETH NOBLE lives by the adage "I can't not write." She doesn't remember a time when she didn't make up stories and eventually she learned how to put words on a page. Those words turned into books and fan fiction that turned into a genuine love of M/M fiction. A part of every day is spent living in worlds she created that are filled with intrigue and espionage. She has a real love for a good mystery complete with murder and twisty plots as well as all things sci-fi, futuristic, and supernatural.
When she's not chronicling the adventures of her many characters, Elizabeth is a veterinary nurse living in her native Cleveland, Ohio. She has three grown children and now happily shares her little, brick house with an adorable mixed breed canine princess, a spunky Cardigan Welsh Corgi and their sidekick, tabby cat. Elizabeth is a fan of baseball, basketball (go Cavs and Indians) and gardening. She can often be found working in her 'outside office' listening to classic rock and plotter her next novel waiting for it to be dark enough to gaze at the stars.
Elizabeth has received a number of amateur writing awards. Since being published, several of her novels have received Honorable Mentions in the Rainbow Awards. Jewel Cave was a runner-up in the Gay Mystery/Thriller category in the 2015 Rainbow Awards. Ringed Love was a winner in the Gay Fantasy Romance category of the 2016 Rainbow Awards.
Astronomy Stuff
Chained Hearts
Gywo
It's On Sale!
Marked Yours
Rainbow Con
Rainbow Snippets
Reader Corner
Tethered Pair
Todd & Nick Ruger
Together Bound

redpajama_set_name: RedPajamaCommonCrawl


Ghavidel, S., F. Imani, S. Khallaghi, E. Gibson, A. Khojaste, M. Gaed, M. Moussa, J. A. Gomez, R. D. Siemens, M. Leveridge, et al., "Classification of prostate cancer grade using temporal ultrasound: in vivo feasibility study", SPIE Medical Imaging: International Society for Optics and Photonics, pp. 97860K–97860K, 2016.
Azizi, S., F. Imani, S. Ghavidel, A. Tahmasebi, J. T. Kwak, S. Xu, B. Turkbey, P. Choyke, P. Pinto, B. Wood, et al., "Detection of prostate cancer using temporal sequences of ultrasound data: a large clinical feasibility study", International journal of computer assisted radiology and surgery, vol. 11, no. 6: Springer Berlin Heidelberg, pp. 947–956, 2016.
Imani, F., S. Ghavidel, P. Abolmaesumi, S. Khallaghi, E. Gibson, A. Khojaste, M. Gaed, M. Moussa, J. A. Gomez, C. Romagnoli, et al., "Fusion of multi-parametric MRI and temporal ultrasound for characterization of prostate cancer: in vivo feasibility study", SPIE Medical Imaging: International Society for Optics and Photonics, pp. 97851K–97851K, 2016.


I have had such a craving for fresh spring vegetables lately! And no wonder since we've been having beautiful weather and Pinterest is overflowing with bright and colorful dishes featuring a variety of Spring's bounty! A few weeks ago, I saw a bacon wrapped asparagus recipe over on FabGrandma's blog. My mouth instantly began to water as I thought about how delicious that combination must taste! So, when Pie and I were at our local farmer's market on Saturday, I grabbed a pound of the tender young spears that they had resting in a bowl of cool water, with the thought of making my own.
I also picked up a few big red sweet peppers and bacon at the local meat market (besides the other fresh veggies and fruit that Pie and I loaded into our basket). These bacon wrapped asparagus and red pepper bundles couldn't be simpler to make. A bit of olive oil, sea salt and pepper, pop them in the oven and you're good to go!
We served our baked asparagus bundles alongside baked sweet potatoes and pan-seared local grass fed beef steak — it was an amazing dinner and I was shocked that both kids and the veggie-hating hubby ate (and enjoyed) the asparagus bundles!
Tender young asparagus stalks and bright red sweet peppers are wrapped in hickory smoked bacon, drizzled in olive oil and baked until crisp and juicy!
Rinse asparagus and trim bottom ½" from stalks.
Cut red pepper into 8 slices, lengthwise.
Separate asparagus spears into bundles of two to three, place one pepper slice onto each.
Starting from bottom, wrap a piece of bacon tightly around spears and pepper, ending about halfway, add another slice and continue wrapping, leaving tip of spears visible.
Place on parchment lined sheet, so they are not touching.
Drizzle olive oil over bundles and sprinkle with sea salt and pepper to taste.
Bake in preheated oven about 15 minutes, then turn on broiler and broil for 5, or until bacon is as crisp as you like.
I could eat these every single day! All that bacon would probably kill me but it would be so worth it!
Thank you for the recipe!! Will try it very soon!!
Because bacon makes everything taste better. ;) My house is full of bacon lovers too, so I know this would go over well on the dinner table.
Bacon makes EVERYTHING better. Fact.
Don't kill me but I'm not a bacon lover lol. But I would make these in a second. I'm hooked on asparagus right now!
They would be good with just one piece of bacon wrapped around each bundle as well!
I just may have to try this! Thanks for sharing, pinned it for future use!
You had me at BACON ;). Would this not make the perfect dish for Christmas dinner. The red and green with BACON! I've got to try it.
These look amazing! It would be a great item to bring to a potluck. Thanks for the recipe!