text:
<?php

if (!defined('ELK'))
	die('No access...');

/**
 * Auth_Controller class, deals with logging in and out members,
 * and the validation of them
 */
class Auth_Controller extends Action_Controller
{
	/**
	 * Entry point in Auth controller
	 * (well no, not really. We route directly to the rest.)
	 *
	 * @see Action_Controller::action_index()
	 */
	public function action_index()
	{
		// What can we do? login page!
		$this->action_login();
	}

	/**
	 * Ask them for their login information. (shows a page for the user to type
	 *  in their username and password.)
	 *  It caches the referring URL in $_SESSION['login_url'].
	 *  It is accessed from ?action=login.
	 *  @uses Login template and language file with the login sub-template.
	 */
	public function action_login()
	{
		global $txt, $context, $scripturl, $user_info;

		// You are already logged in, go take a tour of the boards
		if (!empty($user_info['id']))
			redirectexit();

		// Load the Login template/language file.
		loadLanguage('Login');
		loadTemplate('Login');
		$context['sub_template'] = 'login';

		// Get the template ready.... not really much else to do.
		$context['page_title'] = $txt['login'];
		$context['default_username'] = &$_REQUEST['u'];
		$context['default_password'] = '';
		$context['never_expire'] = false;

		// Add the login chain to the link tree.
		$context['linktree'][] = array(
			'url' => $scripturl . '?action=login',
			'name' => $txt['login'],
		);

		// Set the login URL - will be used when the login process is done (but careful not to send us to an attachment).
		if (isset($_SESSION['old_url']) && strpos($_SESSION['old_url'], 'dlattach') === false && preg_match('~(board|topic)[=,]~', $_SESSION['old_url']) != 0)
			$_SESSION['login_url'] = $_SESSION['old_url'];
		else
			unset($_SESSION['login_url']);

		// Create a one time token.
		createToken('login');
	}

	/**
	 * Actually logs you in.
	 * What it does:
	 * - checks credentials and checks that login was successful.
	 * - it employs protection against a specific IP or user trying to brute force
	 *   a login to an account.
	 * - upgrades password encryption on login, if necessary.
	 * - after successful login, redirects you to $_SESSION['login_url'].
	 * - accessed from ?action=login2, by forms.
	 *
	 * On error, uses the same templates action_login() uses.
	 */
	public function action_login2()
	{
		global $txt, $scripturl, $user_info, $user_settings, $modSettings, $context, $sc;

		// Load cookie authentication and all stuff.
		require_once(SUBSDIR . '/Auth.subs.php');

		// Beyond this point you are assumed to be a guest trying to login.
		if (!$user_info['is_guest'])
			redirectexit();

		// Are you guessing with a script?
		checkSession('post');
		$tk = validateToken('login');
		spamProtection('login');

		// Set the login_url if it's not already set (but careful not to send us to an attachment).
		if ((empty($_SESSION['login_url']) && isset($_SESSION['old_url']) && strpos($_SESSION['old_url'], 'dlattach') === false && preg_match('~(board|topic)[=,]~', $_SESSION['old_url']) != 0) || (isset($_GET['quicklogin']) && isset($_SESSION['old_url']) && strpos($_SESSION['old_url'], 'login') === false))
			$_SESSION['login_url'] = $_SESSION['old_url'];

		// Been guessing a lot, haven't we?
		if (isset($_SESSION['failed_login']) && $_SESSION['failed_login'] >= $modSettings['failed_login_threshold'] * 3)
			fatal_lang_error('login_threshold_fail', 'critical');

		// Set up the cookie length.  (if it's invalid, just fall through and use the default.)
		if (isset($_POST['cookieneverexp']) || (!empty($_POST['cookielength']) && $_POST['cookielength'] == -1))
			$modSettings['cookieTime'] = 3153600;
		elseif (!empty($_POST['cookielength']) && ($_POST['cookielength'] >= 1 || $_POST['cookielength'] <= 525600))
			$modSettings['cookieTime'] = (int) $_POST['cookielength'];

		loadLanguage('Login');

		// Load the template stuff
		loadTemplate('Login');
		$context['sub_template'] = 'login';

		// Set up the default/fallback stuff.
		$context['default_username'] = isset($_POST['user']) ? preg_replace('~&#(\\d{1,7}|x[0-9a-fA-F]{1,6});~', '&#\\1;', htmlspecialchars($_POST['user'], ENT_COMPAT, 'UTF-8')) : '';
		$context['default_password'] = '';
		$context['never_expire'] = $modSettings['cookieTime'] == 525600 || $modSettings['cookieTime'] == 3153600;
		$context['login_errors'] = array($txt['error_occurred']);
		$context['page_title'] = $txt['login'];

		// Add the login chain to the link tree.
		$context['linktree'][] = array(
			'url' => $scripturl . '?action=login',
			'name' => $txt['login'],
		);

		if (!empty($_POST['openid_identifier']) && !empty($modSettings['enableOpenID']))
		{
			require_once(SUBSDIR . '/OpenID.subs.php');
			$open_id = new OpenID();
			if (($open_id->validate($_POST['openid_identifier'])) !== 'no_data')
				return $open_id;
		}

		// You forgot to type your username, dummy!
		if (!isset($_POST['user']) || $_POST['user'] == '')
		{
			$context['login_errors'] = array($txt['need_username']);
			return;
		}

		// No one needs a username that long, plus we only support 80 chars in the db
		if (Util::strlen($_POST['user']) > 80)
			$_POST['user'] = Util::substr($_POST['user'], 0, 80);

		// Hmm... maybe 'admin' will login with no password. Uhh... NO!
		if ((!isset($_POST['passwrd']) || $_POST['passwrd'] == '') && (!isset($_POST['hash_passwrd']) || strlen($_POST['hash_passwrd']) != 40))
		{
			$context['login_errors'] = array($txt['no_password']);
			return;
		}

		// No funky symbols either.
		if (preg_match('~[<>&"\'=\\\]~', preg_replace('~(&#(\\d{1,7}|x[0-9a-fA-F]{1,6});)~', '', $_POST['user'])) != 0)
		{
			$context['login_errors'] = array($txt['error_invalid_characters_username']);
			return;
		}

		// Are we using any sort of integration to validate the login?
		if (in_array('retry', call_integration_hook('integrate_validate_login', array($_POST['user'], isset($_POST['hash_passwrd']) && strlen($_POST['hash_passwrd']) == 40 ? $_POST['hash_passwrd'] : null, $modSettings['cookieTime'])), true))
		{
			$context['login_errors'] = array($txt['login_hash_error']);
			$context['disable_login_hashing'] = true;
			return;
		}

		// Find them... if we can
		$user_settings = loadExistingMember($_POST['user']);

		// Let them try again, it didn't match anything...
		if (empty($user_settings))
		{
			$context['login_errors'] = array($txt['username_no_exist']);
			return;
		}

		// Figure out the password using Elk's encryption - if what they typed is right.
		if (isset($_POST['hash_passwrd']) && strlen($_POST['hash_passwrd']) == 40)
		{
			// Needs upgrading?
			if (strlen($user_settings['passwd']) != 40)
			{
				$context['login_errors'] = array($txt['login_hash_error']);
				$context['disable_login_hashing'] = true;
				unset($user_settings);
				return;
			}
			// Challenge passed.
			elseif ($_POST['hash_passwrd'] == sha1($user_settings['passwd'] . $sc . $tk))
				$sha_passwd = $user_settings['passwd'];
			else
			{
				// Don't allow this!
				validatePasswordFlood($user_settings['id_member'], $user_settings['passwd_flood']);

				$_SESSION['failed_login'] = isset($_SESSION['failed_login']) ? ($_SESSION['failed_login'] + 1) : 1;

				if ($_SESSION['failed_login'] >= $modSettings['failed_login_threshold'])
					redirectexit('action=reminder');
				else
				{
					log_error($txt['incorrect_password'] . ' - ' . $user_settings['member_name'] . '', 'user');

					$context['disable_login_hashing'] = true;
					$context['login_errors'] = array($txt['incorrect_password']);
					unset($user_settings);
					return;
				}
			}
		}
		else
			$sha_passwd = sha1(strtolower($user_settings['member_name']) . un_htmlspecialchars($_POST['passwrd']));

		// Bad password!  Thought you could fool the database?!
		if ($user_settings['passwd'] != $sha_passwd)
		{
			// Let's be cautious, no hacking please. thanx.
			validatePasswordFlood($user_settings['id_member'], $user_settings['passwd_flood']);

			// Maybe we were too hasty... let's try some other authentication methods.
			$other_passwords = array();

			// None of the below cases will be used most of the time (because the salt is normally set.)
			if (!empty($modSettings['enable_password_conversion']) && $user_settings['password_salt'] == '')
			{
				// YaBB SE, Discus, MD5 (used a lot), SHA-1 (used some), SMF 1.0.x, IkonBoard, and none at all.
				$other_passwords[] = crypt($_POST['passwrd'], substr($_POST['passwrd'], 0, 2));
				$other_passwords[] = crypt($_POST['passwrd'], substr($user_settings['passwd'], 0, 2));
				$other_passwords[] = md5($_POST['passwrd']);
				$other_passwords[] = sha1($_POST['passwrd']);
				$other_passwords[] = md5_hmac($_POST['passwrd'], strtolower($user_settings['member_name']));
				$other_passwords[] = md5($_POST['passwrd'] . strtolower($user_settings['member_name']));
				$other_passwords[] = md5(md5($_POST['passwrd']));
				$other_passwords[] = $_POST['passwrd'];

				// This one is a strange one... MyPHP, crypt() on the MD5 hash.
				$other_passwords[] = crypt(md5($_POST['passwrd']), md5($_POST['passwrd']));

				// Snitz style - SHA-256.  Technically, this is a downgrade, but most PHP configurations don't support sha256 anyway.
				if (strlen($user_settings['passwd']) == 64 && function_exists('mhash') && defined('MHASH_SHA256'))
					$other_passwords[] = bin2hex(mhash(MHASH_SHA256, $_POST['passwrd']));

				// phpBB3 users new hashing.  We now support it as well ;).
				$other_passwords[] = phpBB3_password_check($_POST['passwrd'], $user_settings['passwd']);

				// APBoard 2 Login Method.
				$other_passwords[] = md5(crypt($_POST['passwrd'], 'CRYPT_MD5'));
			}
			// The hash should be 40 if it's SHA-1, so we're safe with more here too.
			elseif (!empty($modSettings['enable_password_conversion']) && strlen($user_settings['passwd']) == 32)
			{
				// vBulletin 3 style hashing?  Let's welcome them with open arms \o/.
				$other_passwords[] = md5(md5($_POST['passwrd']) . stripslashes($user_settings['password_salt']));

				// Hmm.. p'raps it's Invision 2 style?
				$other_passwords[] = md5(md5($user_settings['password_salt']) . md5($_POST['passwrd']));

				// Some common md5 ones.
				$other_passwords[] = md5($user_settings['password_salt'] . $_POST['passwrd']);
				$other_passwords[] = md5($_POST['passwrd'] . $user_settings['password_salt']);
			}
			elseif (strlen($user_settings['passwd']) == 40)
			{
				// Maybe they are using a hash from before the password fix.
				$other_passwords[] = sha1(strtolower($user_settings['member_name']) . un_htmlspecialchars($_POST['passwrd']));

				if (!empty($modSettings['enable_password_conversion']))
				{
					// BurningBoard3 style of hashing.
					$other_passwords[] = sha1($user_settings['password_salt'] . sha1($user_settings['password_salt'] . sha1($_POST['passwrd'])));

					// PunBB 1.4 and later
					$other_passwords[] = sha1($user_settings['password_salt'] . sha1($_POST['passwrd']));
				}

				// Perhaps we converted to UTF-8 and have a valid password being hashed differently.
				if (!empty($modSettings['previousCharacterSet']) && $modSettings['previousCharacterSet'] != 'utf8')
				{
					// Try iconv first, for no particular reason.
					if (function_exists('iconv'))
						$other_passwords['iconv'] = sha1(strtolower(iconv('UTF-8', $modSettings['previousCharacterSet'], $user_settings['member_name'])) . un_htmlspecialchars(iconv('UTF-8', $modSettings['previousCharacterSet'], $_POST['passwrd'])));

					// Say it aint so, iconv failed!
					if (empty($other_passwords['iconv']) && function_exists('mb_convert_encoding'))
						$other_passwords[] = sha1(strtolower(mb_convert_encoding($user_settings['member_name'], 'UTF-8', $modSettings['previousCharacterSet'])) . un_htmlspecialchars(mb_convert_encoding($_POST['passwrd'], 'UTF-8', $modSettings['previousCharacterSet'])));
				}
			}
			elseif (strlen($user_settings['passwd']) == 64 && !empty($modSettings['enable_password_conversion']))
			{
				// Yet another downgrade .. PHP-Fusion7
				$other_passwords[] = hash_hmac('sha256', $_POST['passwrd'], $user_settings['password_salt']);

				// Xenforo?
				$other_passwords[] = sha1(sha1($_POST['passwrd']) . $user_settings['password_salt']);
				$other_passwords[] = sha256(sha256($_POST['passwrd']) . $user_settings['password_salt']);
			}

			// ElkArte's sha1 function can give a funny result on Linux (Not our fault!). If we've now got the real one let the old one be valid!
			if (stripos(PHP_OS, 'win') !== 0)
			{
				require_once(SUBSDIR . '/Compat.subs.php');
				$other_passwords[] = sha1_smf(strtolower($user_settings['member_name']) . un_htmlspecialchars($_POST['passwrd']));
			}

			// Allows mods to easily extend the $other_passwords array
			call_integration_hook('integrate_other_passwords', array(&$other_passwords));

			// Whichever encryption it was using, let's make it use ElkArte's now ;).
			if (in_array($user_settings['passwd'], $other_passwords))
			{
				$user_settings['passwd'] = $sha_passwd;
				$user_settings['password_salt'] = substr(md5(mt_rand()), 0, 4);

				// Update the password and set up the hash.
				updateMemberData($user_settings['id_member'], array('passwd' => $user_settings['passwd'], 'password_salt' => $user_settings['password_salt'], 'passwd_flood' => ''));
			}
			// Okay, they for sure didn't enter the password!
			else
			{
				// They've messed up again - keep a count to see if they need a hand.
				$_SESSION['failed_login'] = isset($_SESSION['failed_login']) ? ($_SESSION['failed_login'] + 1) : 1;

				// Hmm... don't remember it, do you?  Here, try the password reminder ;).
				if ($_SESSION['failed_login'] >= $modSettings['failed_login_threshold'])
					redirectexit('action=reminder');
				// We'll give you another chance...
				else
				{
					// Log an error so we know that it didn't go well in the error log.
					log_error($txt['incorrect_password'] . ' - ' . $user_settings['member_name'] . '', 'user');

					$context['login_errors'] = array($txt['incorrect_password']);
					return;
				}
			}
		}
		elseif (!empty($user_settings['passwd_flood']))
		{
			// Let's be sure they weren't a little hacker.
			validatePasswordFlood($user_settings['id_member'], $user_settings['passwd_flood'], true);

			// If we got here then we can reset the flood counter.
			updateMemberData($user_settings['id_member'], array('passwd_flood' => ''));
		}

		// Correct password, but they've got no salt; fix it!
		if ($user_settings['password_salt'] == '')
		{
			$user_settings['password_salt'] = substr(md5(mt_rand()), 0, 4);
			updateMemberData($user_settings['id_member'], array('password_salt' => $user_settings['password_salt']));
		}

		// Check their activation status.
		if (!checkActivation())
			return;

		doLogin();
	}

	/**
	 * Logs the current user out of their account.
	 * It requires that the session hash is sent as well, to prevent automatic logouts by images or javascript.
	 * It redirects back to $_SESSION['logout_url'], if it exists.
	 * It is accessed via ?action=logout;session_var=...
	 *
	 * @param bool $internal if true, it doesn't check the session
	 * @param $redirect
	 */
	public function action_logout($internal = false, $redirect = true)
	{
		global $user_info, $user_settings, $context;

		// Make sure they aren't being auto-logged out.
		if (!$internal)
			checkSession('get');

		require_once(SUBSDIR . '/Auth.subs.php');

		if (isset($_SESSION['pack_ftp']))
			$_SESSION['pack_ftp'] = null;

		// They cannot be open ID verified any longer.
		if (isset($_SESSION['openid']))
			unset($_SESSION['openid']);

		// It won't be first login anymore.
		unset($_SESSION['first_login']);

		// Just ensure they aren't a guest!
		if (!$user_info['is_guest'])
		{
			// Pass the logout information to integrations.
			call_integration_hook('integrate_logout', array($user_settings['member_name']));

			// If you log out, you aren't online anymore :P.
			logOnline($user_info['id'], false);
		}

		// Logout? Let's kill the admin/moderate/other sessions, too.
		$types = array('admin', 'moderate');
		call_integration_hook('integrate_validateSession', array(&$types));
		foreach ($types as $type)
			unset($_SESSION[$type . '_time']);

		$_SESSION['log_time'] = 0;

		// Empty the cookie! (set it in the past, and for id_member = 0)
		setLoginCookie(-3600, 0);

		// And some other housekeeping while we're at it.
		session_destroy();
		if (!empty($user_info['id']))
			updateMemberData($user_info['id'], array('password_salt' => substr(md5(mt_rand()), 0, 4)));

		// Off to the merry board index we go!
		if ($redirect)
		{
			if (empty($_SESSION['logout_url']))
				redirectexit('', $context['server']['needs_login_fix']);
			elseif (!empty($_SESSION['logout_url']) && (substr($_SESSION['logout_url'], 0, 7) !== 'http://' && substr($_SESSION['logout_url'], 0, 8) !== 'https://'))
			{
				unset($_SESSION['logout_url']);
				redirectexit();
			}
			else
			{
				$temp = $_SESSION['logout_url'];
				unset($_SESSION['logout_url']);

				redirectexit($temp, $context['server']['needs_login_fix']);
			}
		}
	}

	/**
	 * Throws guests out to the login screen when guest access is off.
	 * It sets $_SESSION['login_url'] to $_SERVER['REQUEST_URL'].
	 * It uses the 'kick_guest' sub template found in Login.template.php.
	 */
	public function action_kickguest()
	{
		global $txt, $context;

		loadLanguage('Login');
		loadTemplate('Login');
		createToken('login');

		// Never redirect to an attachment
		if (strpos($_SERVER['REQUEST_URL'], 'dlattach') === false)
			$_SESSION['login_url'] = $_SERVER['REQUEST_URL'];

		$context['sub_template'] = 'kick_guest';
		$context['page_title'] = $txt['login'];
	}

	/**
	 * Display a message about the forum being in maintenance mode.
	 * Displays a login screen with sub template 'maintenance'.
	 * It sends a 503 header, so search engines don't index while we're in maintenance mode.
	 */
	public function action_maintenance_mode()
	{
		global $txt, $mtitle, $mmessage, $context;

		loadLanguage('Login');
		loadTemplate('Login');
		createToken('login');

		// Send a 503 header, so search engines don't bother indexing while we're in maintenance mode.
		header('HTTP/1.1 503 Service Temporarily Unavailable');

		// Basic template stuff..
		$context['sub_template'] = 'maintenance';
		$context['title'] = &$mtitle;
		$context['description'] = &$mmessage;
		$context['page_title'] = $txt['maintain_mode'];
	}

	/**
	 * Checks the cookie and update salt.
	 * If successful, it redirects to action=auth;sa=check.
	 * Accessed by ?action=auth;sa=salt.
	 */
	public function action_salt()
	{
		global $user_info, $user_settings, $context, $cookiename;

		// We deal only with logged in folks in here!
		if (!$user_info['is_guest'])
		{
			if (isset($_COOKIE[$cookiename]) && preg_match('~^a:[34]:\{i:0;i:\d{1,8};i:1;s:(0|40):"([a-fA-F0-9]{40})?";i:2;[id]:\d{1,14};(i:3;i:\d;)?\}$~', $_COOKIE[$cookiename]) === 1)
				list (,, $timeout) = @unserialize($_COOKIE[$cookiename]);
			elseif (isset($_SESSION['login_' . $cookiename]))
				list (,, $timeout) = @unserialize($_SESSION['login_' . $cookiename]);
			else
				trigger_error('Auth: Cannot be logged in without a session or cookie', E_USER_ERROR);

			$user_settings['password_salt'] = substr(md5(mt_rand()), 0, 4);
			updateMemberData($user_info['id'], array('password_salt' => $user_settings['password_salt']));

			setLoginCookie($timeout - time(), $user_info['id'], sha1($user_settings['passwd'] . $user_settings['password_salt']));

			redirectexit('action=auth;sa=check;member=' . $user_info['id'], $context['server']['needs_login_fix']);
		}

		// Lets be sure.
		redirectexit();
	}

	/**
	 * Double check the cookie.
	 */
	public function action_check()
	{
		global $user_info, $modSettings, $user_settings;

		// Only our members, please.
		if (!$user_info['is_guest'])
		{
			// Strike!  You're outta there!
			if ($_GET['member'] != $user_info['id'])
				fatal_lang_error('login_cookie_error', false);

			$user_info['can_mod'] = allowedTo('access_mod_center') || (!$user_info['is_guest'] && ($user_info['mod_cache']['gq'] != '0=1' || $user_info['mod_cache']['bq'] != '0=1' || ($modSettings['postmod_active'] && !empty($user_info['mod_cache']['ap']))));
			if ($user_info['can_mod'] && isset($user_settings['openid_uri']) && empty($user_settings['openid_uri']))
			{
				$_SESSION['moderate_time'] = time();
				unset($_SESSION['just_registered']);
			}

			// Some whitelisting for login_url...
			if (empty($_SESSION['login_url']))
				redirectexit();
			elseif (!empty($_SESSION['login_url']) && (substr($_SESSION['login_url'], 0, 7) !== 'http://' && substr($_SESSION['login_url'], 0, 8) !== 'https://'))
			{
				unset($_SESSION['login_url']);
				redirectexit();
			}
			else
			{
				// Best not to clutter the session data too much...
				$temp = $_SESSION['login_url'];
				unset($_SESSION['login_url']);

				redirectexit($temp);
			}
		}

		// It'll never get here... until it does :P
		redirectexit();
	}
}

/**
 * Check activation status of the current user.
 *
 * > 10 Banned with activation status as value - 10
 * 5 = Awaiting COPPA concent
 * 4 = Awaiting Deletion approval
 * 3 = Awaiting Admin approval
 * 2 = Awaiting reactivation from email change
 * 1 = Approved and active
 * 0 = Not active
 */
function checkActivation()
{
	global $context, $txt, $scripturl, $user_settings, $modSettings;

	if (!isset($context['login_errors']))
		$context['login_errors'] = array();

	// What is the true activation status of this account?
	$activation_status = $user_settings['is_activated'] > 10 ? $user_settings['is_activated'] - 10 : $user_settings['is_activated'];

	// Check if the account is activated - COPPA first...
	if ($activation_status == 5)
	{
		$context['login_errors'][] = $txt['coppa_no_concent'] . ' ' . $txt['coppa_need_more_details'] . '';
		return false;
	}
	// Awaiting approval still?
	elseif ($activation_status == 3)
		fatal_lang_error('still_awaiting_approval', 'user');
	// Awaiting deletion, changed their mind?
	elseif ($activation_status == 4)
	{
		if (isset($_REQUEST['undelete']))
		{
			updateMemberData($user_settings['id_member'], array('is_activated' => 1));
			updateSettings(array('unapprovedMembers' => ($modSettings['unapprovedMembers'] > 0 ? $modSettings['unapprovedMembers'] - 1 : 0)));
		}
		else
		{
			$context['disable_login_hashing'] = true;
			$context['login_errors'][] = $txt['awaiting_delete_account'];
			$context['login_show_undelete'] = true;
			return false;
		}
	}
	// Standard activation?
	elseif ($activation_status != 1)
	{
		log_error($txt['activate_not_completed1'] . ' - ' . $user_settings['member_name'] . '', false);

		$context['login_errors'][] = $txt['activate_not_completed1'] . ' ' . $txt['activate_not_completed2'] . '';
		return false;
	}
	return true;
}

/**
 * This function performs the logging in.
 * It sets the cookie, it call hooks, updates runtime settings for the user.
 */
function doLogin()
{
	global $user_info, $user_settings, $maintenance, $modSettings, $context;

	// Load authentication stuffs.
	require_once(SUBSDIR . '/Auth.subs.php');

	// Call login integration functions.
	call_integration_hook('integrate_login', array($user_settings['member_name'], isset($_POST['hash_passwrd']) && strlen($_POST['hash_passwrd']) == 40 ? $_POST['hash_passwrd'] : null, $modSettings['cookieTime']));

	// Get ready to set the cookie...
	$user_info['id'] = $user_settings['id_member'];

	// Bam!  Cookie set.  A session too, just in case.
	setLoginCookie(60 * $modSettings['cookieTime'], $user_settings['id_member'], sha1($user_settings['passwd'] . $user_settings['password_salt']));

	// Reset the login threshold.
	if (isset($_SESSION['failed_login']))
		unset($_SESSION['failed_login']);

	$user_info['is_guest'] = false;
	$user_settings['additional_groups'] = explode(',', $user_settings['additional_groups']);
	$user_info['is_admin'] = $user_settings['id_group'] == 1 || in_array(1, $user_settings['additional_groups']);

	// Are you banned?
	is_not_banned(true);

	// An administrator, set up the login so they don't have to type it again.
	if ($user_info['is_admin'] && isset($user_settings['openid_uri']) && empty($user_settings['openid_uri']))
	{
		// Let's validate if they really want..
		if (!empty($modSettings['auto_admin_session']) && $modSettings['auto_admin_session'] == 1)
			$_SESSION['admin_time'] = time();

		unset($_SESSION['just_registered']);
	}

	// Don't stick the language or theme after this point.
	unset($_SESSION['language'], $_SESSION['id_theme']);

	// We want to know if this is first login
	if (isFirstLogin($user_info['id']))
		$_SESSION['first_login'] = true;
	else
		unset($_SESSION['first_login']);

	// You're one of us: need to know all about you now, IP, stuff.
	$req = request();

	// You've logged in, haven't you?
	updateMemberData($user_info['id'], array('last_login' => time(), 'member_ip' => $user_info['ip'], 'member_ip2' => $req->ban_ip()));

	// Get rid of the online entry for that old guest....
	deleteOnline('ip' . $user_info['ip']);
	$_SESSION['log_time'] = 0;

	// Log this entry, only if we have it enabled.
	if (!empty($modSettings['loginHistoryDays']))
		logLoginHistory($user_info['id'], $user_info['ip'], $user_info['ip2']);

	// Just log you back out if it's in maintenance mode and you AREN'T an admin.
	if (empty($maintenance) || allowedTo('admin_forum'))
		redirectexit('action=auth;sa=check;member=' . $user_info['id'], $context['server']['needs_login_fix']);
	else
		redirectexit('action=logout;' . $context['session_var'] . '=' . $context['session_id'], $context['server']['needs_login_fix']);
}

/**
 * MD5 Encryption used for older passwords. (SMF 1.0.x/YaBB SE 1.5.x hashing)
 *
 * @param string $data
 * @param string $key
 * @return string, the HMAC MD5 of data with key
 */
function md5_hmac($data, $key)
{
	$key = str_pad(strlen($key) <= 64 ? $key : pack('H*', md5($key)), 64, chr(0x00));
	return md5(($key ^ str_repeat(chr(0x5c), 64)) . pack('H*', md5(($key ^ str_repeat(chr(0x36), 64)) . $data)));
}

/**
 * Custom encryption for phpBB3 based passwords.
 *
 * @param string $passwd
 * @param string $passwd_hash
 * @return string
 */
function phpBB3_password_check($passwd, $passwd_hash)
{
	// Too long or too short?
	if (strlen($passwd_hash) != 34)
		return;

	// Range of characters allowed.
	$range = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

	// Tests
	$strpos = strpos($range, $passwd_hash[3]);
	$count = 1 << $strpos;
	$salt = substr($passwd_hash, 4, 8);

	$hash = md5($salt . $passwd, true);
	for (; $count != 0; --$count)
		$hash = md5($hash . $passwd, true);

	$output = substr($passwd_hash, 0, 12);
	$i = 0;
	while ($i < 16)
	{
		$value = ord($hash[$i++]);
		$output .= $range[$value & 0x3f];

		if ($i < 16)
			$value |= ord($hash[$i]) << 8;

		$output .= $range[($value >> 6) & 0x3f];

		if ($i++ >= 16)
			break;

		if ($i < 16)
			$value |= ord($hash[$i]) << 16;

		$output .= $range[($value >> 12) & 0x3f];

		if ($i++ >= 16)
			break;

		$output .= $range[($value >> 18) & 0x3f];
	}

	// Return now.
	return $output;
}


text:
<?php

/**
 *
 * @package CRM
 * @copyright CiviCRM LLC (c) 2004-2015
 * $Id$
 *
 */
class CRM_Core_I18n_Schema {

  /**
   * Drop all views (for use by CRM_Core_DAO::dropAllTables() mostly).
   *
   * @return void
   */
  public static function dropAllViews() {
    $domain = new CRM_Core_DAO_Domain();
    $domain->find(TRUE);
    if (!$domain->locales) {
      return;
    }

    $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);
    $tables = CRM_Core_I18n_SchemaStructure::tables();

    foreach ($locales as $locale) {
      foreach ($tables as $table) {
        CRM_Core_DAO::executeQuery("DROP VIEW IF EXISTS {$table}_{$locale}");
      }
    }
  }

  /**
   * Switch database from single-lang to multi (by adding
   * the first language and dropping the original columns).
   *
   * @param string $locale
   *   the first locale to create (migrate to).
   *
   * @return void
   */
  public static function makeMultilingual($locale) {
    $domain = new CRM_Core_DAO_Domain();
    $domain->find(TRUE);

    // break early if the db is already multi-lang
    if ($domain->locales) {
      return;
    }

    $dao = new CRM_Core_DAO();

    // build the column-adding SQL queries
    $columns = CRM_Core_I18n_SchemaStructure::columns();
    $indices = CRM_Core_I18n_SchemaStructure::indices();
    $queries = array();
    foreach ($columns as $table => $hash) {
      // drop old indices
      if (isset($indices[$table])) {
        foreach ($indices[$table] as $index) {
          $queries[] = "DROP INDEX {$index['name']} ON {$table}";
        }
      }
      // deal with columns
      foreach ($hash as $column => $type) {
        $queries[] = "ALTER TABLE {$table} ADD {$column}_{$locale} {$type}";
        $queries[] = "UPDATE {$table} SET {$column}_{$locale} = {$column}";
        $queries[] = "ALTER TABLE {$table} DROP {$column}";
      }

      // add view
      $queries[] = self::createViewQuery($locale, $table, $dao);

      // add new indices
      $queries = array_merge($queries, array_values(self::createIndexQueries($locale, $table)));
    }

    // execute the queries without i18n rewriting
    foreach ($queries as $query) {
      $dao->query($query, FALSE);
    }

    // update civicrm_domain.locales
    $domain->locales = $locale;
    $domain->save();
  }

  /**
   * Switch database from multi-lang back to single (by dropping
   * additional columns and views and retaining only the selected locale).
   *
   * @param string $retain
   *   the locale to retain.
   *
   * @return void
   */
  public static function makeSinglelingual($retain) {
    $domain = new CRM_Core_DAO_Domain();
    $domain->find(TRUE);
    $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);

    // break early if the db is already single-lang
    if (!$locales) {
      return;
    }

    // lets drop all triggers first
    $logging = new CRM_Logging_Schema();
    $logging->dropTriggers();

    // turn subsequent tables singlelingual
    $tables = CRM_Core_I18n_SchemaStructure::tables();
    foreach ($tables as $table) {
      self::makeSinglelingualTable($retain, $table);
    }

    // update civicrm_domain.locales
    $domain->locales = 'NULL';
    $domain->save();

    //CRM-6963 -fair assumption.
    global $dbLocale;
    $dbLocale = '';

    // now lets rebuild all triggers
    CRM_Core_DAO::triggerRebuild();
  }

  /**
   * Switch a given table from multi-lang to single (by retaining only the selected locale).
   *
   * @param string $retain
   *   the locale to retain.
   * @param string $table
   *   the table containing the column.
   * @param string $class
   *   schema structure class to use to recreate indices.
   *
   * @param array $triggers
   *
   * @return void
   */
  public static function makeSinglelingualTable(
    $retain,
    $table,
    $class = 'CRM_Core_I18n_SchemaStructure',
    $triggers = array()
  ) {
    $domain = new CRM_Core_DAO_Domain();
    $domain->find(TRUE);
    $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);

    // break early if the db is already single-lang
    if (!$locales) {
      return;
    }

    $columns =& $class::columns();
    $indices =& $class::indices();
    $queries = array();
    $dropQueries = array();
    // drop indices
    if (isset($indices[$table])) {
      foreach ($indices[$table] as $index) {
        foreach ($locales as $loc) {
          $queries[] = "DROP INDEX {$index['name']}_{$loc} ON {$table}";
        }
      }
    }

    // deal with columns
    foreach ($columns[$table] as $column => $type) {
      $queries[] = "ALTER TABLE {$table} ADD {$column} {$type}";
      $queries[] = "UPDATE {$table} SET {$column} = {$column}_{$retain}";
      foreach ($locales as $loc) {
        $dropQueries[] = "ALTER TABLE {$table} DROP {$column}_{$loc}";
      }
    }

    // drop views
    foreach ($locales as $loc) {
      $queries[] = "DROP VIEW {$table}_{$loc}";
    }

    // add original indices
    $queries = array_merge($queries, self::createIndexQueries(NULL, $table));

    // execute the queries without i18n rewriting
    $dao = new CRM_Core_DAO();
    foreach ($queries as $query) {
      $dao->query($query, FALSE);
    }

    foreach ($dropQueries as $query) {
      $dao->query($query, FALSE);
    }

    if (!empty($triggers)) {
      if (CRM_Core_Config::isUpgradeMode()) {
        foreach ($triggers as $triggerInfo) {
          $when = $triggerInfo['when'];
          $event = $triggerInfo['event'];
          $triggerName = "{$table}_{$when}_{$event}";
          CRM_Core_DAO::executeQuery("DROP TRIGGER IF EXISTS {$triggerName}");
        }
      }

      // invoke the meta trigger creation call
      CRM_Core_DAO::triggerRebuild($table);
    }
  }

  /**
   * Add a new locale to a multi-lang db, setting
   * its values to the current default locale.
   *
   * @param string $locale
   *   the new locale to add.
   * @param string $source
   *   the locale to copy from.
   *
   * @return void
   */
  public static function addLocale($locale, $source) {
    // get the current supported locales
    $domain = new CRM_Core_DAO_Domain();
    $domain->find(TRUE);
    $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);

    // break early if the locale is already supported
    if (in_array($locale, $locales)) {
      return;
    }

    $dao = new CRM_Core_DAO();

    // build the required SQL queries
    $columns = CRM_Core_I18n_SchemaStructure::columns();
    $indices = CRM_Core_I18n_SchemaStructure::indices();
    $queries = array();
    foreach ($columns as $table => $hash) {
      // add new columns
      foreach ($hash as $column => $type) {
        // CRM-7854: skip existing columns
        if (CRM_Core_DAO::checkFieldExists($table, "{$column}_{$locale}", FALSE)) {
          continue;
        }
        $queries[] = "ALTER TABLE {$table} ADD {$column}_{$locale} {$type}";
        $queries[] = "UPDATE {$table} SET {$column}_{$locale} = {$column}_{$source}";
      }

      // add view
      $queries[] = self::createViewQuery($locale, $table, $dao);

      // add new indices
      $queries = array_merge($queries, array_values(self::createIndexQueries($locale, $table)));
    }

    // execute the queries without i18n rewriting
    foreach ($queries as $query) {
      $dao->query($query, FALSE);
    }

    // update civicrm_domain.locales
    $locales[] = $locale;
    $domain->locales = implode(CRM_Core_DAO::VALUE_SEPARATOR, $locales);
    $domain->save();

    // invoke the meta trigger creation call
    CRM_Core_DAO::triggerRebuild();
  }

  /**
   * Rebuild multilingual indices, views and triggers (useful for upgrades)
   *
   * @param array $locales
   *   locales to be rebuilt.
   * @param string $version
   *   version of schema structure to use.
   *
   * @return void
   */
  public static function rebuildMultilingualSchema($locales, $version = NULL) {
    if ($version) {
      $latest = self::getLatestSchema($version);
      require_once "CRM/Core/I18n/SchemaStructure_{$latest}.php";
      $class = "CRM_Core_I18n_SchemaStructure_{$latest}";
    }
    else {
      $class = 'CRM_Core_I18n_SchemaStructure';
    }
    $indices =& $class::indices();
    $tables =& $class::tables();
    $queries = array();
    $dao = new CRM_Core_DAO();

    // get all of the already existing indices
    $existing = array();
    foreach (array_keys($indices) as $table) {
      $existing[$table] = array();
      $dao->query("SHOW INDEX FROM $table", FALSE);
      while ($dao->fetch()) {
        if (preg_match('/_[a-z][a-z]_[A-Z][A-Z]$/', $dao->Key_name)) {
          $existing[$table][] = $dao->Key_name;
        }
      }
    }

    // from all of the CREATE INDEX queries fetch the ones creating missing indices
    foreach ($locales as $locale) {
      foreach (array_keys($indices) as $table) {
        $allQueries = self::createIndexQueries($locale, $table, $class);
        foreach ($allQueries as $name => $query) {
          if (!in_array("{$name}_{$locale}", $existing[$table])) {
            $queries[] = $query;
          }
        }
      }
    }

    // rebuild views
    foreach ($locales as $locale) {
      foreach ($tables as $table) {
        $queries[] = self::createViewQuery($locale, $table, $dao, $class);
      }
    }

    // rebuild triggers
    $last = array_pop($locales);

    foreach ($queries as $query) {
      $dao->query($query, FALSE);
    }

    // invoke the meta trigger creation call
    CRM_Core_DAO::triggerRebuild();
  }

  /**
   * Rewrite SQL query to use views to access tables with localized columns.
   *
   * @param string $query
   *   the query for rewrite.
   *
   * @return string
   *   the rewritten query
   */
  public static function rewriteQuery($query) {
    global $dbLocale;
    $tables = self::schemaStructureTables();
    foreach ($tables as $table) {
      $query = preg_replace("/([^'\"])({$table})([^_'\"])/", "\\1\\2{$dbLocale}\\3", $query);
    }
    // uncomment the below to rewrite the civicrm_value_* queries
    // $query = preg_replace("/(civicrm_value_[a-z0-9_]+_\d+)([^_])/", "\\1{$dbLocale}\\2", $query);
    return $query;
  }

  /**
   * @param null $version
   * @param bool $force
   *
   * @return array
   */
  public static function schemaStructureTables($version = NULL, $force = FALSE) {
    static $_tables = NULL;
    if ($_tables === NULL || $force) {
      if ($version) {
        $latest = self::getLatestSchema($version);
        // FIXME: Doing require_once is a must here because a call like CRM_Core_I18n_SchemaStructure_4_1_0 makes
        // class loader look for file like - CRM/Core/I18n/SchemaStructure/4/1/0.php which is not what we want to be loaded
        require_once "CRM/Core/I18n/SchemaStructure_{$latest}.php";
        $class = "CRM_Core_I18n_SchemaStructure_{$latest}";
        $tables =& $class::tables();
      }
      else {
        $tables = CRM_Core_I18n_SchemaStructure::tables();
      }
      $_tables = $tables;
    }
    return $_tables;
  }

  /**
   * @param $version
   *
   * @return mixed
   */
  public static function getLatestSchema($version) {
    // remove any .upgrade sub-str from version. Makes it easy to do version_compare & give right result
    $version = str_ireplace(".upgrade", "", $version);

    // fetch all the SchemaStructure versions we ship and sort by version
    $schemas = array();
    foreach (scandir(dirname(__FILE__)) as $file) {
      $matches = array();
      if (preg_match('/^SchemaStructure_([0-9a-z_]+)\.php$/', $file, $matches)) {
        $schemas[] = str_replace('_', '.', $matches[1]);
      }
    }
    usort($schemas, 'version_compare');

    // find the latest schema structure older than (or equal to) $version
    do {
      $latest = array_pop($schemas);
    } while (version_compare($latest, $version, '>'));

    return str_replace('.', '_', $latest);
  }

  /**
   * CREATE INDEX queries for a given locale and table.
   *
   * @param string $locale
   *   locale for which the queries should be created (null to create original indices).
   * @param string $table
   *   table for which the queries should be created.
   * @param string $class
   *   schema structure class to use.
   *
   * @return array
   *   array of CREATE INDEX queries
   */
  private static function createIndexQueries($locale, $table, $class = 'CRM_Core_I18n_SchemaStructure') {
    $indices =& $class::indices();
    $columns =& $class::columns();
    if (!isset($indices[$table])) {
      return array();
    }

    $queries = array();
    foreach ($indices[$table] as $index) {
      $unique = isset($index['unique']) && $index['unique'] ? 'UNIQUE' : '';
      foreach ($index['field'] as $i => $col) {
        // if a given column is localizable, extend its name with the locale
        if ($locale and isset($columns[$table][$col])) {
          $index['field'][$i] = "{$col}_{$locale}";
        }
      }
      $cols = implode(', ', $index['field']);
      $name = $index['name'];
      if ($locale) {
        $name .= '_' . $locale;
      }
      // CRM-7854: skip existing indices
      if (CRM_Core_DAO::checkConstraintExists($table, $name)) {
        continue;
      }
      $queries[$index['name']] = "CREATE {$unique} INDEX {$name} ON {$table} ({$cols})";
    }
    return $queries;
  }

  /**
   * CREATE VIEW query for a given locale and table.
   *
   * @param string $locale
   *   locale of the view.
   * @param string $table
   *   table of the view.
   * @param CRM_Core_DAO $dao
   *   A DAO object to run DESCRIBE queries.
   * @param string $class
   *   schema structure class to use.
   *
   * @return array
   *   array of CREATE INDEX queries
   */
  private static function createViewQuery($locale, $table, &$dao, $class = 'CRM_Core_I18n_SchemaStructure') {
    $columns =& $class::columns();
    $cols = array();
    $dao->query("DESCRIBE {$table}", FALSE);
    while ($dao->fetch()) {
      // view non-internationalized columns directly
      if (!in_array($dao->Field, array_keys($columns[$table])) and
        !preg_match('/_[a-z][a-z]_[A-Z][A-Z]$/', $dao->Field)
      ) {
        $cols[] = $dao->Field;
      }
    }
    // view intrernationalized columns through an alias
    foreach ($columns[$table] as $column => $_) {
      $cols[] = "{$column}_{$locale} {$column}";
    }
    return "CREATE OR REPLACE VIEW {$table}_{$locale} AS SELECT " . implode(', ', $cols) . " FROM {$table}";
  }

  /**
   * @param $info
   * @param null $tableName
   */
  public static function triggerInfo(&$info, $tableName = NULL) {
    // get the current supported locales
    $domain = new CRM_Core_DAO_Domain();
    $domain->find(TRUE);
    if (empty($domain->locales)) {
      return;
    }

    $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales);
    $locale = array_pop($locales);

    // CRM-10027
    if (count($locales) == 0) {
      return;
    }

    $currentVer = CRM_Core_BAO_Domain::version(TRUE);

    if ($currentVer && CRM_Core_Config::isUpgradeMode()) {
      // take exact version so that proper schema structure file in invoked
      $latest = self::getLatestSchema($currentVer);
      require_once "CRM/Core/I18n/SchemaStructure_{$latest}.php";
      $class = "CRM_Core_I18n_SchemaStructure_{$latest}";
    }
    else {
      $class = 'CRM_Core_I18n_SchemaStructure';
    }

    $columns =& $class::columns();

    foreach ($columns as $table => $hash) {
      if ($tableName &&
        $tableName != $table
      ) {
        continue;
      }

      $trigger = array();

      foreach ($hash as $column => $_) {
        $trigger[] = "IF NEW.{$column}_{$locale} IS NOT NULL THEN";
        foreach ($locales as $old) {
          $trigger[] = "IF NEW.{$column}_{$old} IS NULL THEN SET NEW.{$column}_{$old} = NEW.{$column}_{$locale}; END IF;";
        }
        foreach ($locales as $old) {
          $trigger[] = "ELSEIF NEW.{$column}_{$old} IS NOT NULL THEN";
          foreach (array_merge($locales, array(
            $locale,
          )) as $loc) {
            if ($loc == $old) {
              continue;
            }
            $trigger[] = "IF NEW.{$column}_{$loc} IS NULL THEN SET NEW.{$column}_{$loc} = NEW.{$column}_{$old}; END IF;";
          }
        }
        $trigger[] = 'END IF;';
      }

      $sql = implode(' ', $trigger);
      $info[] = array(
        'table' => array($table),
        'when' => 'BEFORE',
        'event' => array('UPDATE'),
        'sql' => $sql,
      );
    }

    // take care of the ON INSERT triggers
    foreach ($columns as $table => $hash) {
      $trigger = array();
      foreach ($hash as $column => $_) {
        $trigger[] = "IF NEW.{$column}_{$locale} IS NOT NULL THEN";
        foreach ($locales as $old) {
          $trigger[] = "SET NEW.{$column}_{$old} = NEW.{$column}_{$locale};";
        }
        foreach ($locales as $old) {
          $trigger[] = "ELSEIF NEW.{$column}_{$old} IS NOT NULL THEN";
          foreach (array_merge($locales, array(
            $locale,
          )) as $loc) {
            if ($loc == $old) {
              continue;
            }
            $trigger[] = "SET NEW.{$column}_{$loc} = NEW.{$column}_{$old};";
          }
        }
        $trigger[] = 'END IF;';
      }

      $sql = implode(' ', $trigger);
      $info[] = array(
        'table' => array($table),
        'when' => 'BEFORE',
        'event' => array('INSERT'),
        'sql' => $sql,
      );
    }
  }

}

redpajama_set_name: RedPajamaGithub


text:
package world;

import cells.WorldCell;
import geometry.Parallelepiped;
import geometry.ParallelepipedSpace;
import geometry.Position;
import lombok.EqualsAndHashCode;
import org.jetbrains.annotations.NotNull;
import util.CollectionObserver;
import util.Difference;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * HashMap-based implementation of CellStorage
 */
@EqualsAndHashCode
public class HashMapCellStorage implements CellStorage {
    private Map<WorldCell, ParallelepipedSpace> storage;

    /**
     * Create a new empty cell storage
     */
    public HashMapCellStorage() {
        storage = new HashMap<>();
    }

    /**
     * Create a new cell storage containing all the CellParallelepiped's
     * from the given collection
     *
     * @param cellParallelepipeds the collection of elements to initially contain
     * @throws NullPointerException if the specified collection is null
     */
    public HashMapCellStorage(@NotNull Collection<CellParallelepiped> cellParallelepipeds) throws NullPointerException {
        storage = new HashMap<>();
        addAll(cellParallelepipeds);
    }

    /**
     * Construct a new cell storage with the same contents as the given storage
     * @param otherStorage storage from which to copy contents
     */
    public HashMapCellStorage(@NotNull CellStorage otherStorage) {
        storage = new HashMap<>();
        addAll(otherStorage.cellParallelepipeds());
    }

    /**
     * Adds given cell cellParallelepiped to the storage
     *
     * @param cellParallelepiped cellParallelepiped to be added
     */
    @Override
    public void add(CellParallelepiped cellParallelepiped) {
        add(cellParallelepiped.parallelepiped, cellParallelepiped.cell);
    }

    private void removeOverlappingRegions(ParallelepipedSpace parallelepipedSpace) {
        storage.values().forEach(parallelepipedSpace::removeAll);
    }

    /**
     * Adds all cellParallelepipeds in the collection to the storage
     *
     * @param cellParallelepipeds cellParallelepipeds to be added
     */
    @Override
    public void addAll(Collection<CellParallelepiped> cellParallelepipeds) {
        cellParallelepipeds.forEach(this::add);
    }

    /**
     * Adds given parallelepiped with assigned worldCell to the storage
     *
     * @param parallelepiped parallelepiped of the worldCell
     * @param material      worldCell of the parallelepiped
     */
    @Override
    public void add(Parallelepiped parallelepiped, WorldCell material) {
        ParallelepipedSpace parallelepipedSpace = new ParallelepipedSpace();
        parallelepipedSpace.add(parallelepiped);
        removeOverlappingRegions(parallelepipedSpace);

        if (storage.containsKey(material)) {
            storage.get(material).addAll(parallelepipedSpace);
        } else {
            storage.put(material, parallelepipedSpace);
        }
    }

    /**
     * Adds given parallelepiped with assigned worldCell to the storage
     *

     * Creates a unit parallelepiped from the given position.
     *

     *
     * @param position  position of the worldCell
     * @param worldCell worldCell of the position
     */
    @Override
    public void add(Position position, WorldCell worldCell) {
        if (contains(position)) {
            return;
        }

        Parallelepiped parallelepiped = new Parallelepiped(position);

        add(parallelepiped, worldCell);
    }

    /**
     * Remove the given position from the storage
     *

     * If this storage does not contain the given position, do nothing.
     *

     *
     * @param position position to be removed
     */
    @Override
    public void remove(Position position) {
        storage.forEach((wc, ps) -> ps.remove(position));
    }

    /**
     * Remove the given parallelepiped from the storage
     *

     * If the storage contains this parallelepiped only partially,
     * remove as much of it as possible.
     * Otherwise, do nothing.
     *

     *
     * @param parallelepiped position to be removed
     */
    @Override
    public void remove(Parallelepiped parallelepiped) {
        storage.forEach((wc, ps) -> ps.remove(parallelepiped));
    }

    /**
     * Remove all positions in the given collection from the storage,
     * if possible
     *
     * @param toRemove positions to be removed
     */
    @Override
    public void removeAll(Collection<Position> toRemove) {
        toRemove.forEach(this::remove);
    }

    /**
     * Produce true if the given position is in this storage, false otherwise
     *
     * @param position position whose presence in this storage is to be tested
     * @return true if the given position is in this storage, false otherwise
     */
    @Override
    public boolean contains(Position position) {
        return storage.values().parallelStream()
                .anyMatch(parallelepipeds -> parallelepipeds.contains(position));
    }

    /**
     * Remove all elements from this CellStorage
     */
    @Override
    public void clear() {
        storage.clear();
    }

    /**
     * Produce true if this CellStorage is empty, false otherwise
     *
     * @return true if this CellStorage is empty, false otherwise
     */
    @Override
    public boolean isEmpty() {
        return storage.values().parallelStream()
                .allMatch(ParallelepipedSpace::isEmpty);
    }

    /**
     * Produce the number of parallelepipeds in this CellStorage
     *
     * @return number of parallelepipeds in this CellStorage
     */
    @Override
    public int size() {
        return storage.values().parallelStream().mapToInt(ParallelepipedSpace::size).sum();
    }

    /**
     * Produce the stream of all cell parallelepipeds in the storage
     *
     * @return stream of all cell parallelepipeds in the storage
     */
    @Override
    public @NotNull Set<CellParallelepiped> cellParallelepipeds() {
        Set<CellParallelepiped> cellParallelepipeds = new HashSet<>();

        for (WorldCell worldCell : storage.keySet()) {
            for (Parallelepiped parallelepiped : storage.get(worldCell)) {
                cellParallelepipeds.add(new CellParallelepiped(parallelepiped, worldCell));
            }
        }

        return cellParallelepipeds;
    }

    /**
     * Produce the set of all positions in the storage
     *
     * @return set of all positions in the storage
     */
    @Override
    public @NotNull Set<Position> positions() {
        Set<Position> positions = new HashSet<>();

        for (ParallelepipedSpace parallelepipedSpace : storage.values()) {
            positions.addAll(parallelepipedSpace.positions().collect(Collectors.toSet()));
        }

        return positions;
    }

    /**
     * Maybe produce the cellParallelepiped containing the given position
     *
     * @param position position that the cellParallelepiped contains
     */
    @Override
    public @NotNull Optional<CellParallelepiped> get(Position position) {
        for (WorldCell worldCell : storage.keySet()) {
            ParallelepipedSpace parallelepipedSpace = storage.get(worldCell);

            Optional<Parallelepiped> optionalParallelepiped = parallelepipedSpace.get(position);

            if (optionalParallelepiped.isPresent()) {
                CellParallelepiped cellParallelepiped =
                        new CellParallelepiped(optionalParallelepiped.get(), worldCell);

                return Optional.of(cellParallelepiped);
            }
        }

        return Optional.empty();
    }

    /**
     * Helps analyzing changes in the storage
     *
     * @return difference between current storage and its last seen version
     */
    @Override
    public @NotNull CollectionObserver<CellParallelepiped> registerCollectionObserver() {
        return new CellStorageObserver(this);
    }

    private class CellStorageObserver implements CollectionObserver<CellParallelepiped> {
        private HashMapCellStorage current;
        private HashMapCellStorage old;

        CellStorageObserver(HashMapCellStorage current) {
            this.current = current;
            this.old = new HashMapCellStorage(current);
        }

        @Override
        public Difference<CellParallelepiped> getDifference() {
            Set<CellParallelepiped> added = new HashSet<>();
            Set<CellParallelepiped> removed = new HashSet<>();

            added.addAll(current.cellParallelepipeds());
            added.removeAll(old.cellParallelepipeds());

            removed.addAll(old.cellParallelepipeds());
            removed.removeAll(current.cellParallelepipeds());

            old.clear();
            old.addAll(current.cellParallelepipeds());

            return new Difference<>(added, removed, new HashMap<>());
        }
    }
}


text:
from _io import Buffer, BufferOverflowError, BufferUnderflowError, BufferInvalidArgumentError

class IOStream(object):
    """abstract class to indicate that something is a stream and capable
    of the basic read and write ops on a buffer"""
    def write(self, buffer, timeout = -1.0):
        """should write available bytes from the buffer into stream and return
        the number of bytes written (could be less than available), or 0 on EOF
        or raise error, or timeout"""

    def read(self, buffer, timeout = -1.0):
        """should read from the stream into buffer and return number of bytes read, or 0 on EOF
        or raise error, or timeout"""
        pass

from concurrence.io.socket import Socket, SocketServer
from concurrence.io.buffered import BufferedReader, BufferedWriter, BufferedStream

#TODO what if more arguments are needed for connect?, eg. passwords etc?
class Connector(object):
    """connector class for connection oriented IO  (TCP), prevents the need for client protocol libraries to hardcode a
    particular way to achieve a connection (e.g. no need to explicitly reference sockets"""
    @classmethod
    def connect(cls, endpoint):
        if isinstance(endpoint, Connector):
            assert False, "TODO"
        else:
            #default is to connect to Socket and endpoint is address
            from concurrence.io.socket import Socket
            from concurrence.timer import Timeout
            return Socket.connect(endpoint, Timeout.current())

class Server(object):
    """server class for connection oriented IO (TCP), prevents the need for server protocol libraries to hardcode a
    particular way to serve a connection (e.g. no need to explicitly reference Server Sockets"""
    @classmethod
    def serve(cls, endpoint, handler):
        if isinstance(endpoint, Server):
            assert False, "TODO"
        else:
            #default is to server using SocketServer, endpoint is addresss
            from concurrence.io.socket import SocketServer
            socket_server = SocketServer(endpoint, handler)
            socket_server.serve()
            return socket_server


text:
package cdzero2hero.web;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;

public class StatelessSessionFilterBugFix implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        chain.doFilter(new HttpServletRequestWrapper((HttpServletRequest) request) {
            @Override
            public Cookie[] getCookies() {
                Cookie[] cookies = super.getCookies();
                return cookies == null ? new Cookie[0] : cookies;
            }
        }, response);
    }

    @Override
    public void destroy() {
    }
}


text:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

/* homework 4.6.1 */

typedef int bool;
#define true 1
#define false 0

typedef struct node
{
    char value;
    int level;
    struct node *left;
    struct node *right;
} NodeT;

NodeT **stack;
int stackPointer;
bool debugMode = false;
int treeHeight = 0;
NodeT *printNull;

/* checks if the expression is in accordance to a math expression */
int checkExpression(char* expr)
{
    int pointer = 0;
    while (*(expr+pointer) != 0)
    {
        if (!(isalpha(*(expr+pointer)) || strchr("+-*/ #", *(expr+pointer))))
        {
            return false;
        }
        pointer++;
    }
    return true;
}

/* exits and prints a message */
void exitError(char *string)
{
    printf("[ERROR] %s", string);
    exit(EXIT_FAILURE);
}

/* reads the math expresion (in values) and its size*/
void readExpression(char **values, int *size)
{
    fprintf(stdout, "[INFO] [READ]\tIntroduce the mathematical expression separated by space in\n");
    fprintf(stdout, "\t\tpostfix form with operands in [a-zA-Z], operations in '+-*/'\n");
    fprintf(stdout, "\t\tand use '#' for unary operations:\n");
    fprintf(stdout, "[INFO] [READ]\t");
    char *buffer = (char*) calloc(1024, sizeof(char));
    fgets(buffer, 1024, stdin);

    *size = 0;
    while (*(buffer+*size) != '\n')
    {
        (*size)++;
    }
    *size = (*size+1)/2;

    char *result = (char*) calloc((*size+1), sizeof(char));
    for (int i=0; i<*size; i++)
    {
        *(result+i) = *(buffer+i*2);
    }

    free(buffer);
    if (checkExpression(result))
    {
        *values = result;
    }
    else
    {
        exitError("[READ]\tThe read expression contains invalid characters.\n");
    }
}

/* initializes a stack with size >= 1 */
void initStack(int size)
{
    if(size < 1)
    {
        exitError("[INIT]\tFailed to initialize stack. Size is less than 1.\n");
        return;
    }
    stack = (NodeT**) calloc(size, sizeof(NodeT*));
    stackPointer = -1;
}

void pushStack(NodeT *node)
{
    if (debugMode)
    {
        printf("[DBUG] [PUSH]\t%c @ %d\n", node->value, stackPointer+1);
    }
    stackPointer++;
    *(stack+stackPointer) = node;
}

/* increase levels the NodeT node and its children */
void increaseLevels(NodeT *node)
{
    if(node == NULL)
    {
        return;
    }
    (node->level)++;
    if (node->level > treeHeight)
    {
        treeHeight = node->level;
    }
    increaseLevels(node->left);
    increaseLevels(node->right);
}

/* returns the pointer to popped NodeT node */
NodeT* popStack()
{
    NodeT *result = *(stack+stackPointer);
    increaseLevels(result);
    if (debugMode)
    {
        printf("[DBUG] [POP]\t%c @ %d\n", result->value, stackPointer);
    }
    *(stack+stackPointer) = NULL;
    stackPointer--;
    return result;
}

/* returns a NodeT based on char val with NULL left and right children */
NodeT* createNode(char val)
{
    NodeT *result = (NodeT*) malloc(sizeof(NodeT));
    result->value = val;
    result->level = 0;
    result->left = NULL;
    result->right = NULL;
    return result;
}

/* transforms the values string in a binary tree */
void createTree(char *values, int size)
{
    for (int i=0; i<size; i++)
    {
        NodeT *aux = createNode(*(values+i));
        if (isalpha(aux->value) || (aux->value=='#'))
        {
            pushStack(aux);
        }
        else if (strchr("+-*/", aux->value))
        {
            NodeT *node = createNode(aux->value);
            node->right = popStack();
            node->left = popStack();

            pushStack(node);
        }
    }
}

/* raises the base to the power of exponent, returns -1 if exponent is negative */
int power(int base, int exponent)
{
    if (exponent < 0)
        return -1;
    int result = 1;
    for (int i=0; i<exponent; i++)
        result *= base;
    return result;
}

/* prints the row with the element in the file */
void printValue(FILE *f, NodeT *node)
{
    if (node->value != -1)
    {
        for (int i=0; i<power(2,treeHeight-node->level)-1; i++)
        {
            fprintf(f, " ");
        }
        fprintf(f, "%c", node->value);
        for (int i=0; i<power(2,treeHeight-node->level)-1; i++)
        {
            fprintf(f, " ");
        }
    }
    else
    {
        for (int i=0; i<power(2,treeHeight-node->level+1)-1; i++)
        {
            fprintf(f, " ");
        }
    }
}

/* prints the elements in the same value */
void recursivePrintValue(FILE *f, NodeT *node, int level)
{
    if (level < node->level)
    {
        return;
    }
    if (level == node->level)
    {
        printValue(f, node);
        fprintf(f, " ");
        if (node == printNull)
        {
            return;
        }
    }
    if (node->left->value == -1)
    {
        node->left->level = node->level+1;
    }
    recursivePrintValue(f, node->left, level);
    if (node->value == -1)
    {
        node->level--;
    }
    if (node->right->value == -1)
    {
        node->right->level = node->level+1;
    }
    recursivePrintValue(f, node->right, level);
}

/* prints the link between node and its children in the file */
void printLinks(FILE *f, NodeT *node, int i)
{
    if (node->value != -1)
    {
        for (int j=0; j<power(2, treeHeight-node->level+1)-1; j++)
        {
            if (j == power(2, treeHeight-node->level)-2-i)
            {
                if (node->left->value != -1)
                    fprintf(f, "/");
                else
                    fprintf(f, " ");
            }
            else if (j == power(2, treeHeight-node->level)+i)
            {
                if (node->right->value != -1)
                    fprintf(f, "\\");
                else
                    fprintf(f, " ");
            }
            else
            {
                fprintf(f, " ");
            }
        }
    }
    else
    {
        for (int j=0; j<power(2, treeHeight-node->level+1)-1; j++)
        {
            fprintf(f, " ");
        }
    }
}

/* prints the links between same levels */
void recursivePrintLinks(FILE *f, NodeT *node, int i, int level)
{
    if (level < node->level)
    {
        return;
    }
    if (level == node->level)
    {
        printLinks(f, node, i);
        fprintf(f, " ");
        if (node == printNull)
        {
            return;
        }
    }
    if (node->left->value == -1)
    {
        node->left->level = node->level+1;
    }
    recursivePrintLinks(f, node->left, i, level);
    if (node->value == -1)
    {
        node->level--;
    }
    if (node->right->value == -1)
    {
        node->right->level = node->level+1;
    }
    recursivePrintLinks(f, node->right, i, level);
}

/* recursively changes NULL values with replacement */
void recursiveFormatTree(NodeT *node, NodeT *replacement)
{
    if ((node->left == NULL) || (node->right == NULL))
    {
        if(node->left == NULL)
        {
            node->left = replacement;
        }
        if(node->right == NULL)
        {
            node->right = replacement;
        }
        return;
    }
    recursiveFormatTree(node->left, replacement);
    recursiveFormatTree(node->right, replacement);
}

/* reformats treeto print spaces when null node is encountered */
void reformatTree()
{
    printNull = (NodeT*) malloc(sizeof(NodeT));
    printNull->value = -1;
    printNull->level = -1;
    printNull->left = printNull;
    printNull->right = printNull;

    recursiveFormatTree(*(stack+stackPointer), printNull);
}

/* prints the tree recursively */
void printTree(char *filename)
{
    FILE* f = fopen(filename, "w");
    reformatTree();

    /* start printing */
    for (int k=0; k<=treeHeight; k++)
    {
        printNull->level = k;
        recursivePrintValue(f, *(stack+stackPointer), k);
        fprintf(f, "\n");
        for (int i=0; i<power(2, treeHeight-k-1); i++)
        {
            recursivePrintLinks(f, *(stack+stackPointer), i, k);
            fprintf(f, "\n");
        }
    }

    printf("[INFO] [PRINT]\tThe tree was printed successfully in the file \"%s\".\n", filename);
    fclose(f);
}

int main()
{
    char *values;
    int size;
    readExpression(&values, &size);

    initStack(size);
    createTree(values, size);
    printTree("tree.txt");

    return EXIT_SUCCESS;
}


text:
package org.apache.webbeans.portable.events.generics;

import javax.enterprise.inject.spi.AnnotatedMember;
import javax.enterprise.inject.spi.Producer;

import org.apache.webbeans.portable.events.ProcessProducerImpl;
import org.apache.webbeans.util.ClassUtil;

@SuppressWarnings("unchecked")
public class GProcessProducer extends ProcessProducerImpl implements GenericProducerObserverEvent
{
    public GProcessProducer(Producer<?> producer, AnnotatedMember<?> annotateMember)
    {
        super(producer,annotateMember);
    }

    @Override
    public Class<?> getBeanClass()
    {
        checkState();
        return getAnnotatedMember().getDeclaringType().getJavaClass();
    }

    @Override
    public Class<?> getProducerOrObserverType()
    {
        checkState();
        return ClassUtil.getClazz(getAnnotatedMember().getBaseType());
    }

}


text:
#include "cvfont.h"
/*
 * Document-class: OpenCV::CvFont
 *
 * Font structure that can be passed to text rendering functions.
 * see CvMat#put_text, CvMat#put_text!
 */

__NAMESPACE_BEGIN_OPENCV
__NAMESPACE_BEGIN_CVFONT

VALUE rb_klass;

int
rb_font_option_line_type(VALUE font_option)
{
  VALUE line_type = LOOKUP_CVMETHOD(font_option, "line_type");
  if (FIXNUM_P(line_type)) {
    return FIX2INT(line_type);
  }
  else if (line_type == ID2SYM(rb_intern("aa"))) {
    return CV_AA;
  }
  return 0;
}

VALUE
rb_class()
{
  return rb_klass;
}

void
define_ruby_class()
{
  if (rb_klass)
    return;
  /*
   * opencv = rb_define_module("OpenCV");
   *
   * note: this comment is used by rdoc.
   */
  VALUE opencv = rb_module_opencv();

  rb_klass = rb_define_class_under(opencv, "CvFont", rb_cObject);
  rb_define_alloc_func(rb_klass, rb_allocate);
  VALUE face = rb_hash_new();
  rb_define_const(rb_klass, "FACE", face);
  rb_hash_aset(face, ID2SYM(rb_intern("simplex")), INT2FIX(CV_FONT_HERSHEY_SIMPLEX));
  rb_hash_aset(face, ID2SYM(rb_intern("plain")), INT2FIX(CV_FONT_HERSHEY_PLAIN));
  rb_hash_aset(face, ID2SYM(rb_intern("duplex")), INT2FIX(CV_FONT_HERSHEY_DUPLEX));
  rb_hash_aset(face, ID2SYM(rb_intern("triplex")), INT2FIX(CV_FONT_HERSHEY_TRIPLEX));
  rb_hash_aset(face, ID2SYM(rb_intern("complex_small")), INT2FIX(CV_FONT_HERSHEY_COMPLEX_SMALL));
  rb_hash_aset(face, ID2SYM(rb_intern("script_simplex")), INT2FIX(CV_FONT_HERSHEY_SCRIPT_SIMPLEX));
  rb_hash_aset(face, ID2SYM(rb_intern("script_complex")), INT2FIX(CV_FONT_HERSHEY_SCRIPT_COMPLEX));

  VALUE default_option = rb_hash_new();
  rb_define_const(rb_klass, "FONT_OPTION", default_option);
  rb_hash_aset(default_option, ID2SYM(rb_intern("hscale")), rb_float_new(1.0));
  rb_hash_aset(default_option, ID2SYM(rb_intern("vscale")), rb_float_new(1.0));
  rb_hash_aset(default_option, ID2SYM(rb_intern("shear")), INT2FIX(0));
  rb_hash_aset(default_option, ID2SYM(rb_intern("thickness")), INT2FIX(1));
  rb_hash_aset(default_option, ID2SYM(rb_intern("line_type")), INT2FIX(8));

  rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1);
  rb_define_method(rb_klass, "face", RUBY_METHOD_FUNC(rb_face), 0);
  rb_define_method(rb_klass, "hscale", RUBY_METHOD_FUNC(rb_hscale), 0);
  rb_define_method(rb_klass, "vscale", RUBY_METHOD_FUNC(rb_vscale), 0);
  rb_define_method(rb_klass, "shear", RUBY_METHOD_FUNC(rb_shear), 0);
  rb_define_method(rb_klass, "thickness", RUBY_METHOD_FUNC(rb_thickness), 0);
  rb_define_method(rb_klass, "line_type", RUBY_METHOD_FUNC(rb_line_type), 0);
  rb_define_method(rb_klass, "italic", RUBY_METHOD_FUNC(rb_italic), 0);
}

VALUE
rb_allocate(VALUE klass)
{
  CvFont *ptr;
  return Data_Make_Struct(klass, CvFont, 0, -1, ptr);
}

/*
 * call-seq:
 *   CvFont.new(face[,font_option]) -> font
 *
 * Create font object.
 * face is font name identifier.
 *
 * Only a subset of Hershey fonts (http://sources.isc.org/utils/misc/hershey-font.txt) are supported now:
 * * :simplex - normal size sans-serif font
 * * :plain - small size sans-serif font
 * * :duplex - normal size sans-serif font (more complex than :simplex)
 * * :complex - normal size serif font
 * * :triplex - normal size serif font (more complex than :complex)
 * * :complex_small - smaller version of :complex
 * * :script_simplex - hand-writing style font
 * * :script_complex - more complex variant of :script_simplex
 *
 * font_option should be Hash include these keys.
 *   :hscale
 *     Horizontal scale. If equal to 1.0, the characters have the original width depending on the font type.
 *     If equal to 0.5, the characters are of half the original width.
 *   :vscale
 *     Vertical scale. If equal to 1.0, the characters have the original height depending on the font type.
 *     If equal to 0.5, the characters are of half the original height.
 *   :shear
 *     Approximate tangent of the character slope relative to the vertical line.
 *     Zero value means a non-italic font, 1.0f means ~45degree slope, etc.
 *   :thickness
 *     Thickness of the text strokes.
 *   :line_type
 *     Type of the strokes, see CvMat#Line description.
 *   :italic
 *     If value is not nil or false that means italic or oblique font.
 *
 * note: font_option's default value is CvFont::FONT_OPTION.
 *
 * e.g. Create Font
 *   OpenCV::CvFont.new(:simplex, :hscale => 2, :vslace => 2, :italic => true)
 *   # create 2x bigger than normal, italic type font.
 */
VALUE
rb_initialize(int argc, VALUE *argv, VALUE self)
{
  VALUE face, font_option;
  rb_scan_args(argc, argv, "11", &face, &font_option);
  Check_Type(face, T_SYMBOL);
  face = rb_hash_aref(rb_const_get(cCvFont::rb_class(), rb_intern("FACE")), face);
  if (NIL_P(face)) {
    rb_raise(rb_eArgError, "undefined face.");
  }
  font_option = FONT_OPTION(font_option);

  try {
    cvInitFont(CVFONT(self),
	       (FIX2INT(face) | FO_ITALIC(font_option)),
	       FO_HSCALE(font_option),
	       FO_VSCALE(font_option),
	       FO_SHEAR(font_option),
	       FO_THICKNESS(font_option),
	       FO_LINE_TYPE(font_option));
  }
  catch (cv::Exception& e) {
    raise_cverror(e);
  }

  return self;
}

VALUE
rb_face(VALUE self)
{
  return INT2FIX(CVFONT(self)->font_face);
}

VALUE
rb_hscale(VALUE self)
{
  return rb_float_new(CVFONT(self)->hscale);
}

VALUE
rb_vscale(VALUE self)
{
  return rb_float_new(CVFONT(self)->vscale);
}

VALUE
rb_shear(VALUE self)
{
  return rb_float_new(CVFONT(self)->shear);
}

VALUE
rb_thickness(VALUE self)
{
  return INT2FIX(CVFONT(self)->thickness);
}

VALUE
rb_line_type(VALUE self)
{
  return INT2FIX(CVFONT(self)->line_type);
}

VALUE
rb_italic(VALUE self)
{
  return ((CVFONT(self)->font_face & CV_FONT_ITALIC) > 0) ? Qtrue : Qfalse;
}

__NAMESPACE_END_CVFONT
__NAMESPACE_END_OPENCV


text:
import numpy as np
import bct
from sklearn.externals import joblib
from my_settings import (bands, source_folder)

from sklearn.ensemble import AdaBoostClassifier
from sklearn.cross_validation import (StratifiedKFold, cross_val_score,
                                      permutation_test_score)
from sklearn.grid_search import GridSearchCV

subjects = [
    "0008", "0009", "0010", "0012", "0014", "0015", "0016", "0017", "0018",
    "0019", "0020", "0021", "0022"
]

cls_all = []
pln_all = []

scores_all = np.empty([4, 10])

results_all = {}

for subject in subjects:
    cls = np.load(source_folder + "graph_data/%s_classic_pow_pre.npy" %
                  subject).item()

    pln = np.load(source_folder + "graph_data/%s_plan_pow_pre.npy" %
                  subject).item()

    cls_all.append(cls)
    pln_all.append(pln)

for k, band in enumerate(bands.keys()):
    data_cls = []
    for j in range(len(cls_all)):
        tmp = cls_all[j][band]
        data_cls.append(
            np.asarray([bct.strengths_und(g) for g in tmp]).mean(axis=0))
    data_pln = []
    for j in range(len(pln_all)):
        tmp = pln_all[j][band]
        data_pln.append(
            np.asarray([bct.strengths_und(g) for g in tmp]).mean(axis=0))
    data_cls = np.asarray(data_cls)
    data_pln = np.asarray(data_pln)

    X = np.vstack([data_cls, data_pln])
    y = np.concatenate([np.zeros(len(data_cls)), np.ones(len(data_pln))])

    cv = StratifiedKFold(y, n_folds=6, shuffle=True)

    model = joblib.load(source_folder +
                        "graph_data/sk_models/eigen_ada_pre_%s.plk" % band)

    score, perm_scores, pval = permutation_test_score(
        model, X, y, cv=cv, n_permutations=5000, n_jobs=1)

    result = {"score": score, "perm_scores": perm_scores, "pval": pval}
    results_all[band] = result

np.save(source_folder + "graph_data/perm_test_eigen_pre.npy", results_all)


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TvdbLib.Data.Comparer
{
  /// <summary>
  /// Compare episodes according to their default episode numbers (aired)
  /// </summary>
  internal class EpisodeComparerAired: IComparer<TvdbEpisode>
  {
    public int Compare(TvdbEpisode x, TvdbEpisode y)
    {
      return x.EpisodeNumber - y.EpisodeNumber;
    }
  }

  /// <summary>
  /// Compare episodes according to their dvd episode number
  /// </summary>
  internal class EpisodeComparerDvd : IComparer<TvdbEpisode>
  {
    public int Compare(TvdbEpisode x, TvdbEpisode y)
    {
      return (int)(x.DvdEpisodeNumber - y.DvdEpisodeNumber);
    }
  }

  /// <summary>
  /// Compare episodes according to their absolute episode number
  /// </summary>
  internal class EpisodeComparerAbsolute : IComparer<TvdbEpisode>
  {
    public int Compare(TvdbEpisode x, TvdbEpisode y)
    {
      return (int)(x.AbsoluteNumber - y.AbsoluteNumber);
    }
  }
}