text:
published: true
title: Street art in Kiev
layout: post
tags:
  - graffiti
date: '2016-08-02 23:00:00 +0300'
---
Alesia and I went hunting for murals around Kiev, thanks to Kate since she sent me a link to [a map](http://kyivmural.com/?lang=en) that marks many of them. I also included public art that you can see outside of a museum or gallery. Which ones are your favorites?

<!--more-->

![Car & slut]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/00.jpeg)
![Working together under the sun]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/01.jpeg)
![Finch and lightbulb]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/02.jpeg)
![Roly-poly dragons]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/03.jpeg)
![Traditional Ukrainian girl]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/04.jpeg)
![Ravens]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/05.jpeg)
![Automobiles]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/06.jpeg)
![Storks]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/07.jpeg)
![Flipping over]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/08.jpeg)
![Warhol-style kid portraits]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/09.jpeg)
![Kitchen utensil horse]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/10.jpeg)
![Made in USSR]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/11.jpeg)
![Time for change]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/12.jpeg)
![Larger than life cats]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/13.jpeg)
![Stack of pillows]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/14.jpeg)
![Immovable blanket and pillow]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/15.jpeg)
![Worm dragon]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/16.jpeg)
![Glasses bench]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/17.jpeg)
![Handy bench]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/18.jpeg)
![Mosaic Little Prince]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/19.jpeg)
![Art or not art]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/20.jpeg)
![Cameras]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/21.jpeg)
![Bee bumper]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/22.jpeg)
![Cossack]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/23.jpeg)
![Worldly cereal]({{site.baseurl}}/images/2016/08/02/street-art-in-kiev/24.jpeg)


text:
package org.cloudbus.cloudsim.network.datacenter;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.cloudbus.cloudsim.Cloudlet;
import org.cloudbus.cloudsim.DatacenterCharacteristics;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.Vm;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.core.CloudSimTags;
import org.cloudbus.cloudsim.core.SimEntity;
import org.cloudbus.cloudsim.core.SimEvent;
import org.cloudbus.cloudsim.lists.VmList;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import uk.ac.york.mhe504.components.CloudDBApp;
import uk.ac.york.mhe504.components.GatewayApp;
import uk.ac.york.mhe504.components.InHouseDBApp;
import uk.ac.york.mhe504.components.MiddlewareApp;
import uk.ac.york.mhe504.models.CloudCostModel;

/**
 * NetDatacentreBroker represents a broker acting on behalf of Datacenter provider. It hides VM
 * management, as vm creation, submission of cloudlets to these VMs and destruction of VMs. <br/>
 * <tt>NOTE</tt>: This class is an example only. It works on behalf of a provider not for users.
 * One has to implement interaction with user broker to this broker.
 *
 * @author Saurabh Kumar Garg
 * @author mhe504@york.ac.uk
 * @since CloudSim Toolkit 3.0
 *
 * The class been extended as part of MigSim.
 *
 */
public class NetDatacenterBroker extends SimEntity {

	public static final int HOST_PES = 16;

	public static final int MAX_VMS_PER_HOST = 1;

	/** The list of submitted VMs. */
	private List<? extends Vm> vmList;

	/** The list of created VMs. */
	private List<? extends Vm> vmsCreatedList;

	/** The list of submitted {@link NetworkCloudlet NetworkCloudlets}. */
	private List<? extends NetworkCloudlet> cloudletList;

	/** The list of submitted {@link AppCloudlet AppCloudlets}. */
	private List<? extends AppCloudlet> appCloudletList;

	/** The list of submitted {@link AppCloudlet AppCloudlets}.
         * @todo attribute appears to be redundant with {@link #appCloudletList}
         */
	private final Map<Integer, Integer> appCloudletRecieved;

	/** The list of submitted {@link Cloudlet Cloudlets}.
         */
	private List<? extends Cloudlet> cloudletSubmittedList;

	/** The list of received {@link Cloudlet Cloudlets}.
         * @todo attribute appears to be redundant with {@link #cloudletSubmittedList}
         */
	private List<? extends Cloudlet> cloudletReceivedList;

	/** The number of submitted cloudlets. */
	private int cloudletsSubmitted;

	/** The number of VMs requested. */
	private int vmsRequested;

	/** The acks sent to VMs. */
	private int vmsAcks;

	/** The number of VMs destroyed. */
	private int vmsDestroyed;

	/** The list of datacenter IDs. */
	private List<Integer> datacenterIdsList;

	/** The datacenter requested IDs list.
         * @todo attribute appears to be redundant with {@link #datacenterIdsList}
         */
	private List<Integer> datacenterRequestedIdsList;

	/** The VMs to datacenters map where each key is a VM id
         * and the corresponding value is the datacenter where the VM is placed. */
	private Map<Integer, Integer> vmsToDatacentersMap;

	/** The datacenter characteristics map where each key
         * is the datacenter id and each value is the datacenter itself. */
	private Map<Integer, DatacenterCharacteristics> datacenterCharacteristicsList;

	private NetworkDatacenter linkDC;

	public boolean createvmflag = true;

	public static int cachedcloudlet = 0;

	private Map<String,Long> tableNameRowNumMap_Migration, tableNameRowNumMap_Runtime;

	//Performance of the migration components, to be loaded from command line args in the future.
	private int CLOUDDB_IOPS = 100;
	private int MIDDLEWARE_IOPS = 500;
	private int GATEWAY_IOPS = 500;

	private int averageRowSizeBytes;

	private CloudCostModel costs;

	/**
	 * Creates a new DatacenterBroker object.
	 *
	 * @param name name to be associated with this entity
	 * @param datacentre
	 * @param averageRowSize
	 * @param tableNames
	 *
	 * @throws Exception the exception
	 *
	 * @pre name != null
	 * @post $none
	 */
	public NetDatacenterBroker(Map<String,Long> migration, Map<String,Long> runtime, NetworkDatacenter datacentre,
			int averageRowSize, CloudCostModel cm, int cloudDbIops, int mwIops, int gtwIops)
					throws Exception {

		super("NetDatacenterBroker");

		Log.printLine("CDB IOPS=" + CLOUDDB_IOPS);

		setCloudCostModel(cm);
		setVmList(new ArrayList<NetworkVm>());
		setVmsCreatedList(new ArrayList<NetworkVm>());
		setCloudletList(new ArrayList<NetworkCloudlet>());
		setAppCloudletList(new ArrayList<AppCloudlet>());
		setCloudletSubmittedList(new ArrayList<Cloudlet>());
		setCloudletReceivedList(new ArrayList<Cloudlet>());
		appCloudletRecieved = new HashMap<Integer, Integer>();

		cloudletsSubmitted = 0;
		setVmsRequested(0);
		setVmsAcks(0);
		setVmsDestroyed(0);

		setDatacenterIdsList(new LinkedList<Integer>());
		setDatacenterRequestedIdsList(new ArrayList<Integer>());
		setVmsToDatacentersMap(new HashMap<Integer, Integer>());
		setDatacenterCharacteristicsList(new HashMap<Integer, DatacenterCharacteristics>());
		tableNameRowNumMap_Migration = migration;
		tableNameRowNumMap_Runtime = runtime;
		averageRowSizeBytes = averageRowSize;

		linkDC = datacentre;
	}

	/**
	 * Sends to the broker the list of cloudlets.
	 *
	 * @param list the list
	 *
	 * @pre list !=null
	 * @post $none
	 */
	public void submitCloudletList(List<? extends NetworkCloudlet> list) {
		getCloudletList().addAll(list);
	}

	public void setLinkDC(NetworkDatacenter alinkDC) {
		linkDC = alinkDC;
	}

	public NetworkDatacenter getLinkDC()
	{
		return linkDC;
	}

	/**
	 * Processes events available for this Broker.
	 *
	 * @param ev a SimEvent object
	 *
	 * @pre ev != null
	 * @post $none
	 */
	@Override
	public void processEvent(SimEvent ev) {
		switch (ev.getTag()) {
		// Resource characteristics request
			case CloudSimTags.RESOURCE_CHARACTERISTICS_REQUEST:
				processResourceCharacteristicsRequest(ev);
				break;
			// Resource characteristics answer
			case CloudSimTags.RESOURCE_CHARACTERISTICS:
				processResourceCharacteristics(ev);
				break;
			// VM Creation answer

			// A finished cloudlet returned
			case CloudSimTags.CLOUDLET_RETURN:
				processCloudletReturn(ev);
				break;
			// if the simulation finishes
			case CloudSimTags.END_OF_SIMULATION:
				shutdownEntity();
				break;
			case CloudSimTags.NextCycle:
				if (NetworkConstants.BASE) {
					createVmsInDatacenterBase(linkDC.getId());
				}

				break;
			// other unknown tags are processed by this method
			default:
				processOtherEvent(ev);
				break;
		}
	}

	/**
	 * Processes the return of a request for the characteristics of a Datacenter.
	 *
	 * @param ev a SimEvent object
	 *
	 * @pre ev != $null
	 * @post $none
	 */
	protected void processResourceCharacteristics(SimEvent ev) {
		DatacenterCharacteristics characteristics = (DatacenterCharacteristics) ev.getData();
		getDatacenterCharacteristicsList().put(characteristics.getId(), characteristics);

		if (getDatacenterCharacteristicsList().size() == getDatacenterIdsList().size()) {
			setDatacenterRequestedIdsList(new ArrayList<Integer>());
			createVmsInDatacenterBase(getDatacenterIdsList().get(0));
		}
	}

	/**
	 * Processes a request for the characteristics of a Datacenter.
	 *
	 * @param ev a SimEvent object
	 *
	 * @pre ev != $null
	 * @post $none
	 */

	protected void processResourceCharacteristicsRequest(SimEvent ev) {
		setDatacenterIdsList(CloudSim.getCloudResourceList());
		setDatacenterCharacteristicsList(new HashMap<Integer, DatacenterCharacteristics>());

		Log.printConcatLine(CloudSim.clock(), ": ", getName(), ": Cloud Resource List received with ",
				getDatacenterIdsList().size(), " resource(s)");

		for (Integer datacenterId : getDatacenterIdsList()) {
			sendNow(datacenterId, CloudSimTags.RESOURCE_CHARACTERISTICS, getId());
		}
	}

	/**
	 * Processes the ack received due to a request for VM creation.
	 *
	 * @param ev a SimEvent object
	 *
	 * @pre ev != null
	 * @post $none
	 */

	/**
	 * Processes a cloudlet return event.
	 *
	 * @param ev a SimEvent object
	 *
	 * @pre ev != $null
	 * @post $none
	 */
	protected void processCloudletReturn(SimEvent ev) {
		Cloudlet cloudlet = (Cloudlet) ev.getData();
		getCloudletReceivedList().add(cloudlet);
		cloudletsSubmitted--;
		// all cloudlets executed
		if (getCloudletList().size() == 0 && cloudletsSubmitted == 0 && NetworkConstants.iteration > 10) {
			Log.printConcatLine(CloudSim.clock(), ": ", getName(), ": All Cloudlets executed. Finishing...");
			clearDatacenters();
			finishExecution();
		} else { // some cloudlets haven't finished yet
			if (getAppCloudletList().size() > 0 && cloudletsSubmitted == 0) {
				// all the cloudlets sent finished. It means that some bount
				// cloudlet is waiting its VM be created
				clearDatacenters();
				createVmsInDatacenterBase(0);
			}

		}
	}

	/**
	 * Processes non-default received events that aren't processed by
         * the {@link #processEvent(org.cloudbus.cloudsim.core.SimEvent)} method.
         * This method should be overridden by subclasses in other to process
         * new defined events.
	 *
	 * @param ev a SimEvent object
	 *
	 * @pre ev != null
	 * @post $none
	 */
	protected void processOtherEvent(SimEvent ev) {
		if (ev == null) {
			Log.printConcatLine(getName(), ".processOtherEvent(): Error - an event is null.");
			return;
		}

		Log.printConcatLine(getName(), ".processOtherEvent(): ",
				"Error - event unknown by this DatacenterBroker.");
	}

	/**
	 * Creates virtual machines in a datacenter and submit/schedule cloudlets to them.
	 *
	 * @param datacenterId Id of the Datacenter to create the VMs
	 *
	 * @pre $none
	 * @post $none
	 */
	protected void createVmsInDatacenterBase(int datacenterId) {
		int requestedVms = 0; //What is the point of this?

		if (createvmflag) {
			createVMs(datacenterId);
			createvmflag = false;
		}

		loadCloudCostModel();

		SoftwareSystemApp softwareSystemApp = new SoftwareSystemApp(AppCloudlet.WEB_APP, NetworkConstants.currentAppId, 0, 0, getId(),tableNameRowNumMap_Runtime,0);
		this.getAppCloudletList().add(softwareSystemApp);
		NetworkConstants.currentAppId++;

		MiddlewareApp middlewareApp = new MiddlewareApp(AppCloudlet.WEB_APP, NetworkConstants.currentAppId, 0, 0, getId(),1);
		getAppCloudletList().add(middlewareApp);
		NetworkConstants.currentAppId++;

		GatewayApp gatewayApp = new GatewayApp(AppCloudlet.WEB_APP, NetworkConstants.currentAppId, 0, 0, getId(),2);
		getAppCloudletList().add(gatewayApp);
		NetworkConstants.currentAppId++;

		InHouseDBApp inHouseDBApp = new InHouseDBApp(AppCloudlet.WEB_APP, NetworkConstants.currentAppId, 0, 0, getId(),tableNameRowNumMap_Migration, averageRowSizeBytes,3);
		getAppCloudletList().add(inHouseDBApp);
		NetworkConstants.currentAppId++;

		CloudDBApp cloudDBApp = new CloudDBApp(AppCloudlet.WEB_APP, NetworkConstants.currentAppId, 0, 1, getId(),tableNameRowNumMap_Migration, 4,
												costs.getDatabaseInstanceCost(), costs.getDatabaseStorageCostPerGB(), costs.getDatabaseTransferCostPerMIOPS());
		getAppCloudletList().add(cloudDBApp);
		NetworkConstants.currentAppId++;

		int k = 0;
		// schedule the application on VMs
		for (AppCloudlet app : this.getAppCloudletList()) {

			List<Integer> vmIds = new ArrayList<Integer>();
			linkDC.getVmList().forEach(n -> vmIds.add(n.getId()));

			if (vmIds != null && !vmIds.isEmpty()) {

				app.createCloudletList();

				for (int i = 0; i < app.getNumberOfVMs(); i++) {

					app.getCloudletList().get(i).setUserId(getId());
					appCloudletRecieved.put(app.getAppID(), app.getNumberOfVMs());
					this.getCloudletSubmittedList().add(app.getCloudletList().get(i));
					cloudletsSubmitted++;

					// Sending cloudlet
					sendNow(
							getVmsToDatacentersMap().get(this.getVmList().get(0).getId()),
							CloudSimTags.CLOUDLET_SUBMIT,
							app.getCloudletList().get(i));
				}
				Log.printLine("app" + (k++));
			}

		}

		addMigrationTasks(middlewareApp,gatewayApp, inHouseDBApp,cloudDBApp);
		addRuntimeTasks(softwareSystemApp,cloudDBApp);

		double numStages = 0.0;
		for (AppCloudlet app : getAppCloudletList())
		{
			for (NetworkCloudlet nc : app.getCloudletList())
			{
				numStages = numStages + nc.stages.size();
			}
		}

		Log.printLine("Number of Stages:" + numStages);

		setAppCloudletList(new ArrayList<AppCloudlet>());

		if (NetworkConstants.iteration < 10) {

			NetworkConstants.iteration++;
			this.schedule(getId(), NetworkConstants.nexttime, CloudSimTags.NextCycle);
		}

		setVmsRequested(requestedVms);
		setVmsAcks(0);
	}

	private double loadCloudCostModel() {
		/* @todo paramaterise ComputeCharge and db
		 */
		try
		{
			File fXmlFile = new File("/home/martyn/git/MigrationSimNew/MigrationSim/InputModels/AWSCostModel.xmi");
			DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
			Document doc = dBuilder.parse(fXmlFile);

			doc.getDocumentElement().normalize();

			NodeList root = doc.getElementsByTagName("costs:UtilisedService");
			if (root.getLength() == 1)
			{
				NodeList items = root.item(0).getChildNodes();

				for (int i=1; i< items.getLength(); i++)
				{
					Element element = (Element)items.item(i);
					if (element != null && element.getAttribute("xsi:type").equals("costs:ComputeCharge"))
					{
						if (element.getAttribute("type").equals("db"))
						{
							return Double.valueOf(element.getAttribute("cph"));
						}
					}

				}

			}
		}
		catch(Exception ex)
		{

		}
		return 0.0;
	}

	private void addRuntimeTasks(SoftwareSystemApp softwareSystemApp, CloudDBApp cloudDBApp)
	{

		Long rowsForCloulet;
		for (NetworkCloudlet nc : softwareSystemApp.getCloudletList())
		{
			nc.stages.add(new ExecutionTaskStage(6));
			rowsForCloulet = tableNameRowNumMap_Runtime.get(nc.getName());
			for (int i = 0; i < rowsForCloulet; i++)
			{
				nc.stages.add(new SendTaskStage(averageRowSizeBytes, cloudDBApp.getVmId(), CloudDBApp.ID_START_VALUE+i));
			}
		}

		for (NetworkCloudlet nc : cloudDBApp.getCloudletList())
		{
			rowsForCloulet = tableNameRowNumMap_Runtime.get(nc.getName());
			for (int i = 0; i < rowsForCloulet; i++)
			{
				nc.stages.add(new ExecutionTaskStage(getQueryExectuionTime_cloudDB(32)));
				nc.stages.add(new RecvTaskStage(softwareSystemApp.getVmId()));
			}
		}

	}

	private void addMigrationTasks(MiddlewareApp middlewareApp, GatewayApp gatewayApp, InHouseDBApp inHouseDBApp, CloudDBApp cloudDBApp) {

		Long numberOfTaks =0l;
		//InhouseDB: Old DB, Not Chargeable
		Long rowsForCloulet;
		for (NetworkCloudlet nc : inHouseDBApp.getCloudletList())
		{
			rowsForCloulet = tableNameRowNumMap_Migration.get(nc.getName());
			nc.stages.add(new ExecutionTaskStage(3));
			for (int i = 0; i < rowsForCloulet; i++)
			{
				numberOfTaks++;
				nc.stages.add(new SendTaskStage(averageRowSizeBytes, middlewareApp.getVmId(), MiddlewareApp.MIDDLEWARE_CLOUDLET_ID));
			}
		}

		//Middleware (DMS)middlewareExectuionTime
		double middlewareExectuionTime = 60.0 /MIDDLEWARE_IOPS;
		//convert to ms
		middlewareExectuionTime = middlewareExectuionTime* 1000;

		NetworkCloudlet middlewareCloudlet = middlewareApp.getCloudletList().get(0);
		NetworkCloudlet gatewayCloulet = gatewayApp.getCloudletList().get(0);
		rowsForCloulet = tableNameRowNumMap_Migration.values().stream().mapToLong(Long::longValue).sum();
		for (int j = 0; j < rowsForCloulet; j++)
		{
			numberOfTaks = numberOfTaks + 3;
			middlewareCloudlet.stages.add(new RecvTaskStage(inHouseDBApp.getVmId()));
			middlewareCloudlet.stages.add(new ExecutionTaskStage(middlewareExectuionTime));
			middlewareCloudlet.stages.add(new SendTaskStage(averageRowSizeBytes, gatewayCloulet.getVmId(), GatewayApp.GATEWAY_CLOUDLET_ID));
		}

		//Middleware (EC2 Gateway)
		double gatewayExectuionTime = 60.0 /GATEWAY_IOPS;
		//convert to ms
		gatewayExectuionTime = gatewayExectuionTime* 1000;
		for (int j = 0; j < rowsForCloulet; j++)
		{
			numberOfTaks = numberOfTaks + 3;
			gatewayCloulet.stages.add(new ExecutionTaskStage(gatewayExectuionTime));
			gatewayCloulet.stages.add(new RecvTaskStage(middlewareCloudlet.getVmId()));
			gatewayCloulet.stages.add(new SendTaskStage(averageRowSizeBytes, cloudDBApp.getVmId(), CloudDBApp.ID_START_VALUE+j));
		}

		//CloudDB, AWS RDS
		for (int i =0; i < cloudDBApp.getCloudletList().size();i++)
		{
			NetworkCloudlet nc = cloudDBApp.getCloudletList().get(i);
			rowsForCloulet = tableNameRowNumMap_Migration.get(nc.getName());
			for (int j = 0; j < rowsForCloulet; j++)
			{
				numberOfTaks = numberOfTaks + 2;
				nc.stages.add(new ExecutionTaskStage(getQueryExectuionTime_cloudDB(32)));
				nc.stages.add(new RecvTaskStage(gatewayCloulet.getVmId()));
			}
		}

		Log.printLine(numberOfTaks);

	}

	public void bindCloudletToVm(int cloudletId, int vmId) {

		for (NetworkCloudlet nc : cloudletList) {
			if (nc.getCloudletId() == cloudletId) {
				nc.setVmId(vmId);
			}
		}

	}

        /**
         * Creates virtual machines in a datacenter
         * @param datacenterId The id of the datacenter where to create the VMs.
         */
	private void createVMs(int datacenterId) {

		int numVMs = linkDC.getHostList().size() * MAX_VMS_PER_HOST;

		for (int i = 0; i < numVMs; i++) {
			int vmid = i;
			int mips = 100;
			long size = 10000; // image size (MB)
			int ram = 16000; // vm memory (MB)
			long bw = 10000;
			int pesNumber = HOST_PES / MAX_VMS_PER_HOST;
			String vmm = "Xen"; // VMM name

			// create VM
			NetworkVm vm = new NetworkVm(
					vmid,
					getId(),
					mips,
					pesNumber,
					ram,
					bw,
					size,
					vmm,
					new NetworkCloudletSpaceSharedScheduler(linkDC));
			linkDC.processVmCreateNetwork(vm);
			// add the VM to the vmList
			getVmList().add(vm);
			getVmsToDatacentersMap().put(vmid, datacenterId);
			getVmsCreatedList().add(VmList.getById(getVmList(), vmid));
		}
	}

	/**
	 * Sends request to destroy all VMs running on the datacenter.
	 *
	 * @pre $none
	 * @post $none /** Destroy the virtual machines running in datacenters.
	 *
	 * @pre $none
	 * @post $none
	 */
	protected void clearDatacenters() {
		for (Vm vm : getVmsCreatedList()) {
			Log.printConcatLine(CloudSim.clock(), ": ", getName(), ": Destroying VM #", vm.getId());
			sendNow(getVmsToDatacentersMap().get(vm.getId()), CloudSimTags.VM_DESTROY, vm);
		}

		getVmsCreatedList().clear();
	}

	/**
	 * Sends an internal event communicating the end of the simulation.
	 *
	 * @pre $none
	 * @post $none
	 */
	private void finishExecution() {
		sendNow(getId(), CloudSimTags.END_OF_SIMULATION);
	}

	@Override
	public void shutdownEntity() {
		Log.printConcatLine(getName(), " is shutting down...");
	}

	@Override
	public void startEntity() {
		Log.printConcatLine(getName(), " is starting...");
		schedule(getId(), 0, CloudSimTags.RESOURCE_CHARACTERISTICS_REQUEST);
	}

	/**
	 * Gets the vm list.
	 *
	 * @param <T> the generic type
	 * @return the vm list
	 */
	@SuppressWarnings("unchecked")
	public <T extends Vm> List<T> getVmList() {
		return (List<T>) vmList;
	}

	/**
	 * Sets the vm list.
	 *
	 * @param <T> the generic type
	 * @param vmList the new vm list
	 */
	protected <T extends Vm> void setVmList(List<T> vmList) {
		this.vmList = vmList;
	}

	/**
	 * Gets the cloudlet list.
	 *
	 * @param <T> the generic type
	 * @return the cloudlet list
	 */
	@SuppressWarnings("unchecked")
	public <T extends NetworkCloudlet> List<T> getCloudletList() {
		return (List<T>) cloudletList;
	}

	/**
	 * Sets the cloudlet list.
	 *
	 * @param <T> the generic type
	 * @param cloudletList the new cloudlet list
	 */
	protected <T extends NetworkCloudlet> void setCloudletList(List<T> cloudletList) {
		this.cloudletList = cloudletList;
	}

	@SuppressWarnings("unchecked")
	public <T extends AppCloudlet> List<T> getAppCloudletList() {
		return (List<T>) appCloudletList;
	}

	public <T extends AppCloudlet> void setAppCloudletList(List<T> appCloudletList) {
		this.appCloudletList = appCloudletList;
	}

	/**
	 * Gets the cloudlet submitted list.
	 *
	 * @param <T> the generic type
	 * @return the cloudlet submitted list
	 */
	@SuppressWarnings("unchecked")
	public <T extends Cloudlet> List<T> getCloudletSubmittedList() {
		return (List<T>) cloudletSubmittedList;
	}

	/**
	 * Sets the cloudlet submitted list.
	 *
	 * @param <T> the generic type
	 * @param cloudletSubmittedList the new cloudlet submitted list
	 */
	protected <T extends Cloudlet> void setCloudletSubmittedList(List<T> cloudletSubmittedList) {
		this.cloudletSubmittedList = cloudletSubmittedList;
	}

	/**
	 * Gets the cloudlet received list.
	 *
	 * @param <T> the generic type
	 * @return the cloudlet received list
	 */
	@SuppressWarnings("unchecked")
	public <T extends Cloudlet> List<T> getCloudletReceivedList() {
		return (List<T>) cloudletReceivedList;
	}

	/**
	 * Sets the cloudlet received list.
	 *
	 * @param <T> the generic type
	 * @param cloudletReceivedList the new cloudlet received list
	 */
	protected <T extends Cloudlet> void setCloudletReceivedList(List<T> cloudletReceivedList) {
		this.cloudletReceivedList = cloudletReceivedList;
	}

	/**
	 * Gets the vm list.
	 *
	 * @param <T> the generic type
	 * @return the vm list
	 */
	@SuppressWarnings("unchecked")
	public <T extends Vm> List<T> getVmsCreatedList() {
		return (List<T>) vmsCreatedList;
	}

	/**
	 * Sets the vm list.
	 *
	 * @param <T> the generic type
	 * @param vmsCreatedList the vms created list
	 */
	protected <T extends Vm> void setVmsCreatedList(List<T> vmsCreatedList) {
		this.vmsCreatedList = vmsCreatedList;
	}

	/**
	 * Gets the vms requested.
	 *
	 * @return the vms requested
	 */
	protected int getVmsRequested() {
		return vmsRequested;
	}

	/**
	 * Sets the vms requested.
	 *
	 * @param vmsRequested the new vms requested
	 */
	protected void setVmsRequested(int vmsRequested) {
		this.vmsRequested = vmsRequested;
	}

	/**
	 * Gets the vms acks.
	 *
	 * @return the vms acks
	 */
	protected int getVmsAcks() {
		return vmsAcks;
	}

	/**
	 * Sets the vms acks.
	 *
	 * @param vmsAcks the new vms acks
	 */
	protected void setVmsAcks(int vmsAcks) {
		this.vmsAcks = vmsAcks;
	}

	/**
	 * Increment vms acks.
	 */
	protected void incrementVmsAcks() {
		vmsAcks++;
	}

	/**
	 * Gets the vms destroyed.
	 *
	 * @return the vms destroyed
	 */
	protected int getVmsDestroyed() {
		return vmsDestroyed;
	}

	/**
	 * Sets the vms destroyed.
	 *
	 * @param vmsDestroyed the new vms destroyed
	 */
	protected void setVmsDestroyed(int vmsDestroyed) {
		this.vmsDestroyed = vmsDestroyed;
	}

	/**
	 * Gets the datacenter ids list.
	 *
	 * @return the datacenter ids list
	 */
	protected List<Integer> getDatacenterIdsList() {
		return datacenterIdsList;
	}

	/**
	 * Sets the datacenter ids list.
	 *
	 * @param datacenterIdsList the new datacenter ids list
	 */
	protected void setDatacenterIdsList(List<Integer> datacenterIdsList) {
		this.datacenterIdsList = datacenterIdsList;
	}

	/**
	 * Gets the vms to datacenters map.
	 *
	 * @return the vms to datacenters map
	 */
	protected Map<Integer, Integer> getVmsToDatacentersMap() {
		return vmsToDatacentersMap;
	}

	/**
	 * Sets the vms to datacenters map.
	 *
	 * @param vmsToDatacentersMap the vms to datacenters map
	 */
	protected void setVmsToDatacentersMap(Map<Integer, Integer> vmsToDatacentersMap) {
		this.vmsToDatacentersMap = vmsToDatacentersMap;
	}

	/**
	 * Gets the datacenter characteristics list.
	 *
	 * @return the datacenter characteristics list
	 */
	protected Map<Integer, DatacenterCharacteristics> getDatacenterCharacteristicsList() {
		return datacenterCharacteristicsList;
	}

	/**
	 * Sets the datacenter characteristics list.
	 *
	 * @param datacenterCharacteristicsList the datacenter characteristics list
	 */
	protected void setDatacenterCharacteristicsList(
			Map<Integer, DatacenterCharacteristics> datacenterCharacteristicsList) {
		this.datacenterCharacteristicsList = datacenterCharacteristicsList;
	}

	/**
	 * Gets the datacenter requested ids list.
	 *
	 * @return the datacenter requested ids list
	 */
	protected List<Integer> getDatacenterRequestedIdsList() {
		return datacenterRequestedIdsList;
	}

	/**
	 * Sets the datacenter requested ids list.
	 *
	 * @param datacenterRequestedIdsList the new datacenter requested ids list
	 */
	protected void setDatacenterRequestedIdsList(List<Integer> datacenterRequestedIdsList) {
		this.datacenterRequestedIdsList = datacenterRequestedIdsList;
	}

	public long getTotalRuntimeTasks() {
		return tableNameRowNumMap_Runtime.values().stream().mapToLong(Long::longValue).sum();
	}

	public double getQueryExectuionTime_cloudDB() {
		return (60.0/CLOUDDB_IOPS)*1000;
	}

	public double getQueryExectuionTime_cloudDB(int correction) {
		return (60.0/(CLOUDDB_IOPS+correction))*1000;
	}

	public CloudCostModel getCloudCostModel() {
		return costs;
	}

	public void setCloudCostModel(CloudCostModel costs) {
		this.costs = costs;
	}

}

redpajama_set_name: RedPajamaGithub


text:
<!DOCTYPE html>
<html>
  <head>
    <title>Title</title>
    <meta charset="utf-8">
    <style>
      @import url(https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz);
      @import url(https://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic);
      @import url(https://fonts.googleapis.com/css?family=Ubuntu+Mono:400,700,400italic);

      body { font-family: 'Droid Serif'; }
      h1, h2, h3 {
        font-family: 'Yanone Kaffeesatz';
        font-weight: normal;
      }
      .remark-code, .remark-inline-code { font-family: 'Ubuntu Mono'; }

      .image-30 img {
			width: 30%;
      }

      .big-image img {
			width: 80%;
			margin-top: 15%;
      }

    </style>
  </head>
  <body>
    <textarea id="source">

class: center, middle

# Docker opens the Doors for IoT

.center[.image-50[![sketch](exciting_times_ahead.jpg)]]

***

Dieter Reuter [@Quintus23M](https://twitter.com/Quintus23M)

<!---
.center[.image-30[![sketch](hypriot_logo_white_bg_1920.png)]]
-->

Hypriot Team [@HypriotTweets](https://twitter.com/HypriotTweets) – https://blog.hypriot.com

***

[IoT Conference 2017, Munich](https://iotcon.de/session/docker-opens-the-doors-for-iot/) / March 15th, 2017

---

class: center, middle

# Docker opens the Doors for IoT

.center[.image-50[![sketch](exciting_times_ahead.jpg)]]

***

Dieter Reuter [@Quintus23M](https://twitter.com/Quintus23M)

<!---
.center[.image-30[![sketch](bee42_logo1.png)]]
-->

[@bee42solutions](https://twitter.com/bee42solutions) – https://bee42.com

***

[IoT Conference 2017, Munich](https://iotcon.de/session/docker-opens-the-doors-for-iot/) / March 15th, 2017

---

# Agenda

1. Introduction

2. IoT Challenges

3. Goals

4. Docker Advantages

5. Proof of Concept

6. Summary

---

# Introduction

...it's NOT about me...

**Dieter Reuter**

  - Consultant [@bee42solutions](https://twitter.com/bee42solutions) 🐝

  - Hacker & Pirate by night

  - Working with Docker since >3 years

  - [Docker Captain](https://www.docker.com/community/docker-captains) 🐳, 66 world wide

**--> I'm pushing Docker to ARM & IoT since >2.5 years**

---

# Introduction

...it's all about team work

**Hypriot Team [@HypriotTweets](https://twitter.com/HypriotTweets) https://blog.hypriot.com**

  - five individuals: Andreas, Dieter, Govinda, Mathias, Stefan

  - broad range of skill sets: Devs, DevOps, Trainers, Consulants

  - Open Source project to run Docker on ARM & IoT devices

**--> We've built HypriotOS, a Docker-enabled OS for Raspberry Pi**

---

# Introduction

...it's all about team work

**bee42 solutions gmbh 🐝 https://bee42.com**

   - DevOps company

   - Digital Transformation

   - System Architects & Consultants

   - Trainings for DevOps, Containers & Docker

**--> We're scaling Docker containers - in a different way!**

---

# IoT Challenges

We'll get a huge number of devices...

- Development

- Delivery / Deployment

- Updates (new features, bug fixes)

- Security

- Low bandwidth

---

# Goals

Containers and the Internet of Things

- evangelizing to use Docker container on ARM boards

- convincing Docker containers for IoT applications

- enabling the Docker ecosystem on low-powered devices

*Gartner says 6.4 billion connected "Things" will be in use in 2016, up 30 percent from 2015*

*In turn, that number is expected to further explode by 2020, where the IoT market will include 20.8 billion things*

**--> pushing the Docker technology into the IoT world**

---

# Docker Advantages

- Containers are isolated

- Containers are portable

- Containers can be really small

- it's easy to "install" software as a container

- an update is just to start a new container

**--> Docker helps to deliver Apps to IoT devices**

---

# Docker Development Stack

- Developers: Docker4Mac, Docker4Windows, Docker on Linux

- Testing: locally, on-premises (Jenkins, GitLab), Travis-CI, Circle-CI, CodeShip

- Production: backend services for Cloud & Private Cloud

- Deploy apps as containers on IoT devices (Linux on Intel, ARMv7, AARCH64, ...)

---

# Requirements for Docker on ARM

- Hardware min: 1x Core, ARMv6, 256MB memory

- Linux Kernel w/ Docker related kernel modules

- Operating System: Ubuntu, Debian, Alpine, Buildroot/Yocto, ...

- Docker tools: Engine, Compose, Machine

**--> Docker is already building binaries for ARMv6/7 and AARCH64**

---
# Proof of Concept

Building a complete OS to use Docker on ARM / IoT devices...

.center[.image-30[![sketch](docker_pirate_raspberry_plus_docker-tools.png)]]

**--> complete Docker toolset on ARM**

---

# PoC - Easy Building Blocks

  - small and simple pieces

  - easy to understand

  - easy to develop

  - easy to maintain

**--> combine it like LEGO bricks**

---

# PoC - Full Transparency

  - develop locally (Vagrant + Docker)

  - automated build server (Travis + Docker)

  - automated testing (ServerSpec)

  - automated releasing (GitHub releases)

**--> every single detail is visible**

---

# PoC - Parts and Ideas

HypriotOS

  - a Debian-based root filesystem (32 and 64-bit)

  - a board specific layer
    - Linux kernel
    - firmware
    - bootloader

  - a common layer
    - Hypriot specific settings and tools
    - Docker Engine
    - Docker Compose, Docker Machine

**--> creating ready-to-run SD card images**

---

# PoC - Open Source Everything

All these parts are already open sourced at GitHub https://github.com/hypriot

  - root filesystem: https://github.com/hypriot/os-rootfs

  - raw image: https://github.com/hypriot/image-builder-raw

  - Raspberry Pi: https://github.com/hypriot/image-builder-rpi

Come and try it out

  - hack on it

  - improve it

**--> it's all Open Source**

---

# Summary

Container are ready for IoT

- easier development w/ Docker (Windows, macOS, Linux)

- faster time-to-market

- security built-in w/ container isolation

- easier updates: new features/value, security fixes

**--> Docker already supports ARM 32bit / 64bit**

---

# Thank You

and let's stay in contact:

**Dieter Reuter, bee42 solutions gmbh**

- [@bee42solutions](https://twitter.com/bee42solutions) - https://bee42.com

- Find me on Twitter: [@Quintus23M](https://twitter.com/Quintus23M) or [@HypriotTweets](https://twitter.com/HypriotTweets)

- Hypriot Blog: http://blog.hypriot.com

    </textarea>
    <script src="https://gnab.github.io/remark/downloads/remark-latest.min.js">
    </script>
    <script>
      var slideshow = remark.create();
    </script>
  </body>
</html>


text:
<?php
/**
 * This file is part of GameQ.
 *
 * GameQ is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * GameQ is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * Unreal Tournament 3 Protocol Class
 *
 * NOTE:  The return from UT3 via the GameSpy 3 protocol is anything but consistent.  You may
 * notice different results even on the same server queried at different times.  No real way to fix
 * this problem currently.
 *
 * @author Austin Bischoff <austin@codebeard.com>
 */
class GameQ_Protocols_Ut3 extends GameQ_Protocols_Gamespy3
{
	protected $name = "ut3";
	protected $name_long = "Unreal Tournament 3";

	protected $port = 6500;

	/**
	 * Process all the data at once
	 * @see GameQ_Protocols_Gamespy3::process_all()
	 */
	protected function process_all()
	{
		// Run the parent but we need to change some data
		$result = parent::process_all();

		// Move some stuff around
        $this->move_result($result, 'hostname', 'OwningPlayerName');
        $this->move_result($result, 'p1073741825', 'mapname');
        $this->move_result($result, 'p1073741826', 'gametype');
        $this->move_result($result, 'p1073741827', 'servername');
        $this->move_result($result, 'p1073741828', 'custom_mutators');
        $this->move_result($result, 'gamemode',    'open');
        $this->move_result($result, 's32779',      'gamemode');
        $this->move_result($result, 's0',          'bot_skill');
        $this->move_result($result, 's6',          'pure_server');
        $this->move_result($result, 's7',          'password');
        $this->move_result($result, 's8',          'vs_bots');
        $this->move_result($result, 's10',         'force_respawn');
        $this->move_result($result, 'p268435704',  'frag_limit');
        $this->move_result($result, 'p268435705',  'time_limit');
        $this->move_result($result, 'p268435703',  'numbots');
        $this->move_result($result, 'p268435717',  'stock_mutators');

        // Put custom mutators into an array
        if(isset($result['custom_mutators']))
        {
            $result['custom_mutators'] = explode("\x1c", $result['custom_mutators']);
        }

        // Delete some unknown stuff
        $this->delete_result($result, array('s1','s9','s11','s12','s13','s14'));

    	// Return the result
		return $result;
	}

	// UT3 Hack, yea I know it doesnt belong here. UT3 is such a mess it needs its own version of GSv3
    //$data = str_replace(array("\x00p1073741829\x00", "p1073741829\x00", "p268435968\x00"), '', $data);
}


text:
package com.planet_ink.coffee_mud.Common;
import com.planet_ink.coffee_mud.Libraries.interfaces.*;
import com.planet_ink.coffee_mud.Libraries.interfaces.XMLLibrary.XMLpiece;
import com.planet_ink.coffee_mud.core.interfaces.*;
import com.planet_ink.coffee_mud.core.*;
import com.planet_ink.coffee_mud.core.CMSecurity.SecGroup;
import com.planet_ink.coffee_mud.core.collections.*;
import com.planet_ink.coffee_mud.core.exceptions.CMException;
import com.planet_ink.coffee_mud.Abilities.interfaces.*;
import com.planet_ink.coffee_mud.Areas.interfaces.*;
import com.planet_ink.coffee_mud.Behaviors.interfaces.*;
import com.planet_ink.coffee_mud.CharClasses.interfaces.*;
import com.planet_ink.coffee_mud.Commands.interfaces.*;
import com.planet_ink.coffee_mud.Common.interfaces.*;
import com.planet_ink.coffee_mud.Common.interfaces.AccountStats.PrideStat;
import com.planet_ink.coffee_mud.Common.interfaces.TimeClock.TimePeriod;
import com.planet_ink.coffee_mud.Exits.interfaces.*;
import com.planet_ink.coffee_mud.Items.interfaces.*;
import com.planet_ink.coffee_mud.Locales.interfaces.*;
import com.planet_ink.coffee_mud.MOBS.StdMOB;
import com.planet_ink.coffee_mud.MOBS.interfaces.*;
import com.planet_ink.coffee_mud.Races.interfaces.*;

import java.util.*;

public class DefaultPlayerStats implements PlayerStats
{
	@Override public String ID(){return "DefaultPlayerStats";}
	@Override public String name() { return ID();}
	protected final static int TELL_STACK_MAX_SIZE=50;
	protected final static int GTELL_STACK_MAX_SIZE=50;

	protected long			 hygiene		= 0;
	protected int			 theme			= Area.THEME_FANTASY;
	protected String[]		 xtraValues		= null;
	protected String		 lastIP			= "";
	protected long  		 lLastDateTime	= System.currentTimeMillis();
	protected long  		 lastUpdated	= 0;
	protected int   		 channelMask;
	protected String		 email			= "";
	protected String		 password		= "";
	protected String		 colorStr		= "";
	protected String		 prompt			= "";
	protected String		 poofin			= "";
	protected String		 poofout		= "";
	protected String		 tranpoofin		= "";
	protected String		 tranpoofout	= "";
	protected String		 announceMsg	= "";
	protected String		 savedPose		= "";
	protected String		 notes			= "";
	protected int   		 wrap			= 78;
	protected int   		 pageBreak		= CMProps.getIntVar(CMProps.Int.PAGEBREAK);
	protected int[] 		 birthday		= null;
	protected MOB   		 replyTo		= null;
	protected int   		 replyType		= 0;
	protected long  		 replyTime		= 0;
	protected Set<String>	 friends		= new SHashSet<String>();
	protected Set<String>	 ignored		= new SHashSet<String>();
	protected List<String>	 tellStack		= new SVector<String>();
	protected List<String>	 gtellStack		= new SVector<String>();
	protected List<String>	 titles			= new SVector<String>();
	protected PlayerAccount  account		= null;
	protected SecGroup		 securityFlags	= new SecGroup(new CMSecurity.SecFlag[]{});
	protected long			 accountExpires	= 0;
	protected RoomnumberSet  visitedRoomSet	= null;
	protected Set<String>	 introductions	= new SHashSet<String>();
	protected long[]	 	 prideExpireTime= new long[TimeClock.TimePeriod.values().length];
	protected int[][]		 prideStats		= new int[TimeClock.TimePeriod.values().length][AccountStats.PrideStat.values().length];
	protected ItemCollection extItems;

	protected Map<String,String>	alias	= new STreeMap<String,String>();
	protected Map<String,Integer>	legacy	= new STreeMap<String,Integer>();

	protected TriadVector<Integer, Long, String>	levelInfo		= new TriadVector<Integer, Long, String>();

	public DefaultPlayerStats()
	{
		super();
		xtraValues=CMProps.getExtraStatCodesHolder(this);
		extItems=(ItemCollection)CMClass.getCommon("WeakItemCollection");
	}

	@Override
	public CMObject newInstance()
	{
		try
		{
			return getClass().newInstance();
		}
		catch(final Exception e)
		{
			return new DefaultPlayerStats();
		}
	}

	@Override public void initializeClass(){}

	@Override
	public CMObject copyOf()
	{
		try
		{
			final DefaultPlayerStats O=(DefaultPlayerStats)this.clone();
			O.levelInfo=new TriadVector<Integer, Long, String>();
			O.levelInfo.addAll(levelInfo);
			if(visitedRoomSet!=null)
				O.visitedRoomSet=(RoomnumberSet)visitedRoomSet.copyOf();
			else
				O.visitedRoomSet=null;
			O.securityFlags=securityFlags.copyOf();
			O.friends=new SHashSet<String>(friends);
			O.ignored=new SHashSet<String>(ignored);
			O.tellStack=new SVector<String>(tellStack);
			O.gtellStack=new SVector<String>(gtellStack);
			O.titles=new SVector<String>(titles);
			O.alias=new SHashtable<String,String>(alias);
			O.legacy=new SHashtable<String,Integer>(legacy);
			O.xtraValues=(xtraValues==null)?null:(String[])xtraValues.clone();
			O.extItems=(ItemCollection)extItems.copyOf();
			return O;
		}
		catch(final CloneNotSupportedException e)
		{
			return new DefaultPlayerStats();
		}
	}

	@Override
	public String getLastIP()
	{
		return lastIP;
	}

	@Override
	public void setLastIP(String ip)
	{
		lastIP=ip;
		if(account != null)
			account.setLastIP(ip);
	}

	@Override
	public String getEmail()
	{
		if(account != null)
			return account.getEmail();
		if(email==null)
			return "";
		return email;
	}

	@Override
	public void setEmail(String newAdd)
	{
		email=newAdd;
		if(account != null)
			account.setEmail(newAdd);
	}

	@Override
	public int getTheme()
	{
		return theme;
	}

	@Override
	public void setTheme(int theme)
	{
		this.theme=theme;
	}

	@Override
	public long getLastUpdated()
	{
		return lastUpdated;
	}

	@Override
	public void setLastUpdated(long time)
	{
		lastUpdated=time;
		if(account != null)
			account.setLastUpdated(time);
	}

	@Override
	public long getLastDateTime()
	{
		return lLastDateTime;
	}

	@Override
	public void setLastDateTime(long C)
	{
		lLastDateTime=C;
		if(account != null)
			account.setLastDateTime(C);
	}

	@Override
	public String getPasswordStr()
	{
		return (account!=null)?account.getPasswordStr():password;
	}

	@Override
	public void setPassword(String newPassword)
	{
		if(CMProps.getBoolVar(CMProps.Bool.HASHPASSWORDS)
		&&(!CMLib.encoder().isARandomHashString(newPassword)))
			password=CMLib.encoder().makeRandomHashString(newPassword);
		else
			password=newPassword;
		if(account != null)
			account.setPassword(password);
	}

	@Override
	public boolean matchesPassword(String checkPass)
	{
		if(account!=null)
			return account.matchesPassword(checkPass);
		if(CMLib.encoder().isARandomHashString(password))
			return CMLib.encoder().checkAgainstRandomHashString(checkPass, password);
		return checkPass.equalsIgnoreCase(password);
	}

	@Override
	public int getWrap()
	{
		return wrap;
	}

	@Override
	public void setWrap(int newWrap)
	{
		if(newWrap > CMStrings.SPACES.length())
			newWrap=CMStrings.SPACES.length();
		wrap=newWrap;
	}

	@Override
	public int getPageBreak()
	{
		return pageBreak;
	}

	@Override
	public void setPageBreak(int newBreak)
	{
		pageBreak=newBreak;
	}

	@Override
	public String getNotes()
	{
		return notes;
	}

	@Override
	public void setNotes(String newnotes)
	{
		notes=newnotes;
	}

	@Override
	public void setChannelMask(int newMask)
	{
		channelMask=newMask;
	}

	@Override
	public int getChannelMask()
	{
		return channelMask;
	}

	@Override
	public MOB getReplyToMOB()
	{
		return replyTo;
	}

	@Override
	public int getReplyType()
	{
		return replyType;
	}

	@Override
	public long getReplyToTime()
	{
		return replyTime;
	}

	@Override
	public void setReplyTo(MOB mob, int replyType)
	{
		replyTo=mob;
		this.replyType=replyType;
	}

	@Override
	public void setPrompt(String newPrompt)
	{
		prompt=newPrompt;
	}

	@Override
	public String getColorStr()
	{
		return colorStr;
	}

	@Override
	public void setColorStr(String newColors)
	{
		colorStr=newColors;
	}

	@Override
	public String getAnnounceMessage()
	{
		return announceMsg;
	}

	@Override
	public void setAnnounceMessage(String msg)
	{
		announceMsg=msg;
	}

	@Override
	public String getSavedPose()
	{
		return savedPose;
	}

	@Override
	public void setSavedPose(String msg)
	{
		savedPose=msg;
	}

	@Override
	public String getPrompt()
	{
		if((prompt==null)||(prompt.length()==0))
		{
			prompt=CMProps.getVar(CMProps.Str.DEFAULTPROMPT);
			if((prompt==null)||(prompt.length()==0))
				return "^N%E<^h%hhp ^m%mm ^v%vmv^N>";
		}
		return prompt;
	}

	@Override
	public boolean isIntroducedTo(String name)
	{
		return introductions.contains(name.toUpperCase().trim());
	}

	@Override
	public void introduceTo(String name)
	{
		if((!isIntroducedTo(name))&&(name.trim().length()>0))
			introductions.add(name.toUpperCase().trim());
	}

	public SHashSet<String> getHashFrom(String str)
	{
		final SHashSet<String> h=new SHashSet<String>();
		if((str==null)||(str.length()==0))
			return h;
		str=CMStrings.replaceAll(str,"<FRIENDS>","");
		str=CMStrings.replaceAll(str,"<IGNORED>","");
		str=CMStrings.replaceAll(str,"<INTROS>","");
		str=CMStrings.replaceAll(str,"</INTROS>","");
		str=CMStrings.replaceAll(str,"</FRIENDS>","");
		str=CMStrings.replaceAll(str,"</IGNORED>","");
		int x=str.indexOf(';');
		while(x>=0)
		{
			final String fi=str.substring(0,x).trim();
			if(fi.length()>0)
				h.add(fi);
			str=str.substring(x+1);
			x=str.indexOf(';');
		}
		if(str.trim().length()>0)
			h.add(str.trim());
		return h;
	}

	@Override
	public void addTellStack(String msg)
	{
		if(tellStack.size()>TELL_STACK_MAX_SIZE)
			tellStack.remove(0);
		tellStack.add(msg);
	}

	@Override
	public List<String> getTellStack()
	{
		return new ReadOnlyList<String>(tellStack);
	}

	private RoomnumberSet roomSet()
	{
		if(visitedRoomSet==null)
			visitedRoomSet=((RoomnumberSet)CMClass.getCommon("DefaultRoomnumberSet"));
		return visitedRoomSet;
	}
	@Override
	public void addGTellStack(String msg)
	{
		if(gtellStack.size()>GTELL_STACK_MAX_SIZE)
			gtellStack.remove(0);
		gtellStack.add(msg);
	}

	@Override
	public List<String> getGTellStack()
	{
		return new ReadOnlyList<String>(gtellStack);
	}

	@Override
	public Set<String> getFriends()
	{
		if(account != null)
			return account.getFriends();
		return friends;
	}
	@Override
	public Set<String> getIgnored()
	{
		if(account != null)
			return account.getIgnored();
		return ignored;
	}

	@Override
	public String[] getAliasNames()
	{
		return alias.keySet().toArray(new String[0]);
	}

	@Override
	public String getAlias(String named)
	{
		if(alias.containsKey(named.toUpperCase().trim()))
			return alias.get(named.toUpperCase().trim());
		return "";
	}
	@Override
	public void addAliasName(String named)
	{
		named=named.toUpperCase().trim();
		if(getAlias(named).length()==0)
			alias.put(named,"");
	}
	@Override
	public void delAliasName(String named)
	{
		alias.remove(named.toUpperCase().trim());
	}
	@Override
	public void setAlias(String named, String value)
	{
		alias.put(named.toUpperCase().trim(),value);
	}

	public String getAliasXML()
	{
		if(alias.size()==0)
			return "";
		final StringBuilder str=new StringBuilder("");
		alias.remove("");
		for(final String key : alias.keySet())
			str.append("<ALIAS CMD=\"").append(key).append("\" VAL=\"").append(CMLib.xml().parseOutAngleBracketsAndQuotes(alias.get(key))).append("\" />");
		return str.toString();
	}

	public String getLegacyXML()
	{
		if(legacy.size()==0)
			return "";
		final StringBuilder str=new StringBuilder("");
		for(final String key : legacy.keySet())
			str.append("<LEGACY CAT=\"").append(key).append("\" LVL=\"").append(legacy.get(key)).append("\" />");
		return str.toString();
	}

	@Override
	public String getActiveTitle()
	{
		if((titles==null)||(titles.size()==0))
			return null;
		final String s=titles.get(0);
		if((s.length()<2)||(s.charAt(0)!='{')||(s.charAt(s.length()-1)!='}'))
			return s;
		return s.substring(1,s.length()-1);
	}

	@Override
	public List<String> getTitles()
	{
		return titles;
	}
	private String getTitleXML()
	{
		if(titles.size()==0)
			return "";
		for(int t=titles.size()-1;t>=0;t--)
		{
			final String s=titles.get(t);
			if(s.length()==0)
				titles.remove(t);
		}
		final StringBuilder str=new StringBuilder("");
		for(int t=0;t<titles.size();t++)
		{
			final String s=titles.get(t);
			str.append("<TITLE>"+CMLib.xml().parseOutAngleBrackets(CMLib.coffeeFilter().safetyFilter(s))+"</TITLE>");
		}
		return str.toString();
	}

	@Override
	public String getPoofIn()
	{
		return poofin;
	}

	@Override
	public String getPoofOut()
	{
		return poofout;
	}

	@Override
	public String getTranPoofIn()
	{
		return tranpoofin;
	}
	@Override
	public String getTranPoofOut()
	{
		return tranpoofout;
	}

	@Override
	public int[] getBirthday()
	{
		return birthday;
	}

	@Override
	public int initializeBirthday(TimeClock clock, int ageHours, Race R)
	{
		if(clock == null)
			clock=CMLib.time().globalClock();
		birthday=new int[4];
		birthday[0]=clock.getDayOfMonth();
		birthday[1]=clock.getMonth();
		birthday[2]=clock.getYear();
		birthday[3]=clock.getYear();
		while(ageHours>15)
		{
			birthday[2]-=1;
			ageHours-=15;
		}
		if(ageHours>0)
		{
			birthday[1]=CMLib.dice().roll(1,clock.getMonthsInYear(),0);
			birthday[0]=CMLib.dice().roll(1,clock.getDaysInMonth(),0);
		}
		final int month=clock.getMonth();
		final int day=clock.getDayOfMonth();
		if((month<birthday[1])||((month==birthday[1])&&(birthday[0]<day)))
			return (R.getAgingChart()[Race.AGE_YOUNGADULT]+clock.getYear()-birthday[2])-1;
		return (R.getAgingChart()[Race.AGE_YOUNGADULT]+clock.getYear()-birthday[2]);
	}

	protected String getPrivateList(final Set<String> h)
	{
		if((h==null)||(h.size()==0))
			return "";
		final StringBuffer list=new StringBuffer("");
		for (final String string : h)
			list.append((string)+";");
		return list.toString();
	}

	@Override
	public void bumpPrideStat(final PrideStat stat, final int amt)
	{
		final long now=System.currentTimeMillis();
		if(stat!=null)
		for(final TimeClock.TimePeriod period : TimeClock.TimePeriod.values())
		{
			if(period==TimeClock.TimePeriod.ALLTIME)
				prideStats[period.ordinal()][stat.ordinal()]+=amt;
			else
			{
				if(now>prideExpireTime[period.ordinal()])
				{
					for(final AccountStats.PrideStat stat2 : AccountStats.PrideStat.values())
						prideStats[period.ordinal()][stat2.ordinal()]=0;
					prideExpireTime[period.ordinal()]=period.nextPeriod();
				}
				prideStats[period.ordinal()][stat.ordinal()]+=amt;
			}
		}
	}

	@Override
	public int getPrideStat(final TimePeriod period, final PrideStat stat)
	{
		if((period==null)||(stat==null))
			return 0;
		return prideStats[period.ordinal()][stat.ordinal()];
	}

	@Override
	public String getXML()
	{
		final String f=getPrivateList(getFriends());
		final String i=getPrivateList(getIgnored());
		final String t=getPrivateList(introductions);
		final StringBuffer rest=new StringBuffer("");
		final String[] codes=getStatCodes();
		for(int x=getSaveStatIndex();x<codes.length;x++)
		{
			final String code=codes[x].toUpperCase();
			rest.append("<"+code+">"+CMLib.xml().parseOutAngleBrackets(getStat(code))+"</"+code+">");
		}
		rest.append("<NEXTPRIDEPERIODS>").append(CMParms.toTightStringList(prideExpireTime)).append("</NEXTPRIDEPERIODS>");
		rest.append("<PRIDESTATS>");
		for(final TimeClock.TimePeriod period : TimeClock.TimePeriod.values())
			rest.append(CMParms.toTightStringList(prideStats[period.ordinal()])).append(";");
		rest.append("</PRIDESTATS>");

		return ((f.length()>0)?"<FRIENDS>"+f+"</FRIENDS>":"")
			+((i.length()>0)?"<IGNORED>"+i+"</IGNORED>":"")
			+((t.length()>0)?"<INTROS>"+t+"</INTROS>":"")
			+"<WRAP>"+wrap+"</WRAP>"
			+"<THEME>"+theme+"</THEME>"
			+"<PAGEBREAK>"+pageBreak+"</PAGEBREAK>"
			+((account!=null)?("<ACCOUNT>"+account.getAccountName()+"</ACCOUNT>"):"")
			+getTitleXML()
			+getAliasXML()
			+getLegacyXML()
			+"<ACCTEXP>"+accountExpires+"</ACCTEXP>"
			+((birthday!=null)?"<BIRTHDAY>"+CMParms.toStringList(birthday)+"</BIRTHDAY>":"")
			+((poofin.length()>0)?"<POOFIN>"+CMLib.xml().parseOutAngleBrackets(poofin)+"</POOFIN>":"")
			+((notes.length()>0)?"<NOTES>"+CMLib.xml().parseOutAngleBrackets(notes)+"</NOTES>":"")
			+((poofout.length()>0)?"<POOFOUT>"+CMLib.xml().parseOutAngleBrackets(poofout)+"</POOFOUT>":"")
			+((announceMsg.length()>0)?"<ANNOUNCE>"+CMLib.xml().parseOutAngleBrackets(announceMsg)+"</ANNOUNCE>":"")
			+((savedPose.length()>0)?"<POSE>"+CMLib.xml().parseOutAngleBrackets(savedPose)+"</POSE>":"")
			+((tranpoofin.length()>0)?"<TRANPOOFIN>"+CMLib.xml().parseOutAngleBrackets(tranpoofin)+"</TRANPOOFIN>":"")
			+((tranpoofout.length()>0)?"<TRANPOOFOUT>"+CMLib.xml().parseOutAngleBrackets(tranpoofout)+"</TRANPOOFOUT>":"")
			+"<DATES>"+this.getLevelDateTimesStr()+"</DATES>"
			+"<SECGRPS>"+CMLib.xml().parseOutAngleBrackets(getSetSecurityFlags(null))+"</SECGRPS>"
			+roomSet().xml()
			+rest.toString();
	}

	private void setBirthday(String bday)
	{
		if((bday!=null)&&(bday.length()>0))
		{
			final List<String> V=CMParms.parseCommas(bday,true);
			birthday=new int[4];
			for(int v=0;(v<V.size()) && (v<birthday.length);v++)
				birthday[v]=CMath.s_int(V.get(v));
			if(V.size()<4)
			{
				final TimeClock C=CMLib.time().globalClock();
				birthday[3]=C.getYear();
			}
		}
	}

	private void setAliasXML(List<XMLpiece> xml)
	{
		alias.clear();
		for (final XMLpiece piece : xml)
		{
			if((piece.tag.equals("ALIAS"))&&(piece.parms!=null))
			{
				final String command=CMLib.xml().getParmValue(piece.parms, "CMD");
				final String value=CMLib.xml().getParmValue(piece.parms, "VAL");
				if((command!=null)&&(value!=null))
					alias.put(command, CMLib.xml().restoreAngleBrackets(value));
			}
		}
		int a=-1;
		while((++a)>=0)
		{
			final String name=CMLib.xml().getValFromPieces(xml,"ALIAS"+a);
			final String value=CMLib.xml().getValFromPieces(xml,"ALIASV"+a);
			if((name.length()==0)||(value.length()==0))
				break;
			alias.put(name.toUpperCase().trim(),CMLib.xml().restoreAngleBrackets(value));
		}
	}

	private void setLegacyXML(List<XMLpiece> xml)
	{
		legacy.clear();
		for (final XMLpiece piece : xml)
		{
			if((piece.tag.equals("LEGACY"))&&(piece.parms!=null))
			{
				final String category=CMLib.xml().getParmValue(piece.parms, "CAT");
				final String levelStr=CMLib.xml().getParmValue(piece.parms, "LVL");
				if((category!=null)&&(levelStr!=null))
					legacy.put(category, Integer.valueOf(levelStr));
			}
		}
	}

	private void setTitleXML(List<XMLpiece> xml)
	{
		titles.clear();
		for (final XMLpiece piece : xml)
		{
			if(piece.tag.equals("TITLE"))
				titles.add(CMLib.xml().restoreAngleBrackets(piece.value));
		}
		int t=-1;
		while((++t)>=0)
		{
			final String title=CMLib.xml().restoreAngleBrackets(CMLib.xml().getValFromPieces(xml,"TITLE"+t));
			if(title.length()==0)
				break;
			titles.add(title);
		}

	}

	@Override
	public void setXML(String xmlStr)
	{
		account = null;
		if(xmlStr==null)
			return;
		final XMLLibrary xmlLib=CMLib.xml();
		final boolean debug=CMSecurity.isDebugging(CMSecurity.DbgFlag.PLAYERSTATS);
		if(debug)
			Log.debugOut("XML="+xmlStr);
		final List<XMLLibrary.XMLpiece> xml = xmlLib.parseAllXML(xmlStr);
		String str=xmlLib.getValFromPieces(xml,"FRIENDS");
		if(debug)
			Log.debugOut("FRIENDS="+str);
		friends.clear();
		friends.addAll(getHashFrom(str));
		str=xmlLib.getValFromPieces(xml,"IGNORED");
		if(debug)
			Log.debugOut("IGNORED="+str);
		ignored.clear();
		ignored.addAll(getHashFrom(str));
		str=xmlLib.getValFromPieces(xml,"INTROS");
		if(debug)
			Log.debugOut("INTROS="+str);
		introductions.clear();
		introductions.addAll(getHashFrom(str));
		str=xmlLib.getValFromPieces(xml, "THEME");
		if(debug)
			Log.debugOut("THEME="+str);
		if(CMath.isInteger(str))
			theme=CMath.s_int(str);
		str = xmlLib.getValFromPieces(xml,"ACCTEXP");
		if(debug)
			Log.debugOut("ACCTEXP="+str);
		if((str!=null)&&(str.length()>0))
			setAccountExpiration(CMath.s_long(str));
		else
		{
			final Calendar C=Calendar.getInstance();
			C.add(Calendar.DATE,CMProps.getIntVar(CMProps.Int.TRIALDAYS));
			setAccountExpiration(C.getTimeInMillis());
		}
		str=xmlLib.getValFromPieces(xml,"WRAP");
		if(debug)
			Log.debugOut("WRAP="+str);
		if(CMath.isInteger(str))
			setWrap(CMath.s_int(str));
		str=xmlLib.getValFromPieces(xml,"PAGEBREAK");
		if(debug)
			Log.debugOut("PAGEBREAK="+str);
		if(CMath.isInteger(str))
			pageBreak=CMath.s_int(str);
		else
			pageBreak=CMProps.getIntVar(CMProps.Int.PAGEBREAK);
		str=xmlLib.restoreAngleBrackets(xmlLib.getValFromPieces(xml,"SECGRPS"));
		if(debug)
			Log.debugOut("SECGRPS="+str);
		getSetSecurityFlags(str);
		setAliasXML(xml);
		setTitleXML(xml);
		setLegacyXML(xml);
		str=xmlLib.getValFromPieces(xml,"BIRTHDAY");
		if(debug)
			Log.debugOut("BIRTHDAY="+str);
		setBirthday(str);

		poofin=xmlLib.getValFromPieces(xml,"POOFIN");
		if(debug)
			Log.debugOut("POOFIN="+poofin);
		if(poofin==null)
			poofin="";
		poofin=xmlLib.restoreAngleBrackets(poofin);

		poofout=xmlLib.getValFromPieces(xml,"POOFOUT");
		if(debug)
			Log.debugOut("POOFOUT="+poofout);
		if(poofout==null)
			poofout="";
		poofout=xmlLib.restoreAngleBrackets(poofout);

		tranpoofin=xmlLib.getValFromPieces(xml,"TRANPOOFIN");
		if(debug)
			Log.debugOut("TRANPOOFIN="+tranpoofin);
		if(tranpoofin==null)
			tranpoofin="";
		tranpoofin=xmlLib.restoreAngleBrackets(tranpoofin);

		tranpoofout=xmlLib.getValFromPieces(xml,"TRANPOOFOUT");
		if(debug)
			Log.debugOut("TRANPOOFOUT="+tranpoofout);
		if(tranpoofout==null)
			tranpoofout="";
		tranpoofout=xmlLib.restoreAngleBrackets(tranpoofout);

		announceMsg=xmlLib.getValFromPieces(xml,"ANNOUNCE");
		if(debug)
			Log.debugOut("ANNOUNCE="+announceMsg);
		if(announceMsg==null)
			announceMsg="";
		announceMsg=xmlLib.restoreAngleBrackets(announceMsg);

		savedPose=xmlLib.getValFromPieces(xml,"POSE");
		if(debug)
			Log.debugOut("POSE="+savedPose);
		if(savedPose==null)
			savedPose="";
		savedPose=xmlLib.restoreAngleBrackets(savedPose);

		notes=xmlLib.getValFromPieces(xml,"NOTES");
		if(debug)
			Log.debugOut("NOTES="+notes);
		if(notes==null)
			notes="";
		notes=xmlLib.restoreAngleBrackets(notes);

		str=xmlLib.getValFromPieces(xml,"DATES");
		if(debug)
			Log.debugOut("DATES="+str);
		if(str==null)
			str="";
		// now parse all the level date/times
		int lastNum=Integer.MIN_VALUE;
		levelInfo.clear();
		if(str.length()>0)
		{
			final List<String> sets=CMParms.parseSemicolons(str,true);
			for(int ss=0;ss<sets.size();ss++)
			{
				final String sStr=sets.get(ss);
				final List<String> twin=CMParms.parseCommas(sStr,true);
				if((twin.size()!=2)&&(twin.size()!=3))
					continue;
				if(CMath.s_int(twin.get(0))>=lastNum)
				{
					lastNum=CMath.s_int(twin.get(0));
					levelInfo.addElement(Integer.valueOf(lastNum),
											  Long.valueOf(CMath.s_long(twin.get(1))),
											  (twin.size()>2)?(String)twin.get(2):"");
				}
			}
		}
		if(levelInfo.size()==0)
			levelInfo.addElement(Integer.valueOf(0),Long.valueOf(System.currentTimeMillis()),"");
		str = xmlLib.getValFromPieces(xml,"AREAS");
		if(debug)
			Log.debugOut("AREAS="+str);
		if(str!=null)
			roomSet().parseXML("<AREAS>"+str+"</AREAS>");
		else
			roomSet().parseXML("<AREAS />");
		final String[] codes=getStatCodes();
		for(int i=getSaveStatIndex();i<codes.length;i++)
		{
			str=xmlLib.getValFromPieces(xml,codes[i].toUpperCase());
			if(str==null)
				str="";
			setStat(codes[i].toUpperCase(),xmlLib.restoreAngleBrackets(str));
		}
		final String[] nextPeriods=xmlLib.getValFromPieces(xml, "NEXTPRIDEPERIODS").split(",");
		final String[] prideStats=xmlLib.getValFromPieces(xml, "PRIDESTATS").split(";");
		final Pair<Long,int[]>[] finalPrideStats = CMLib.players().parsePrideStats(nextPeriods, prideStats);
		for(final TimeClock.TimePeriod period : TimeClock.TimePeriod.values())
			if(period.ordinal()<finalPrideStats.length)
			{
				this.prideExpireTime[period.ordinal()]=finalPrideStats[period.ordinal()].first.longValue();
				this.prideStats[period.ordinal()]=finalPrideStats[period.ordinal()].second;
			}

		str = xmlLib.getValFromPieces(xml,"ACCOUNT");
		if(debug)
			Log.debugOut("ACCOUNT="+str);
		if(CMProps.getIntVar(CMProps.Int.COMMONACCOUNTSYSTEM)>1)
		{
			if((str != null)&&(str.length()>0))
				account = CMLib.players().getLoadAccount(str);
		}
	}

	private String getLevelDateTimesStr()
	{
		if(levelInfo.size()==0)
			levelInfo.add(Integer.valueOf(0),Long.valueOf(System.currentTimeMillis()),"");
		final StringBuilder buf=new StringBuilder("");
		for(int ss=0;ss<levelInfo.size();ss++)
		{
			buf.append(levelInfo.elementAtFirst(ss).toString()).append(",");
			buf.append(levelInfo.elementAtSecond(ss).toString()).append(",");
			buf.append(levelInfo.elementAtThird(ss)).append(";");
		}
		return buf.toString();
	}

	@Override
	public String getSetSecurityFlags(String newFlags)
	{
		if(newFlags != null)
		{
			securityFlags=CMSecurity.instance().createGroup("", CMParms.parseSemicolons(newFlags,true));
		}
		return securityFlags.toString(';');

	}

	@Override
	public CMSecurity.SecGroup getSecurityFlags()
	{
		return securityFlags;
	}

	@Override
	public void setPoofs(String poofIn, String poofOut, String tranPoofIn, String tranPoofOut)
	{
		poofin=poofIn;
		poofout=poofOut;
		tranpoofin=tranPoofIn;
		tranpoofout=tranPoofOut;
	}

	@Override
	public long getHygiene()
	{
		return hygiene;
	}

	@Override
	public void setHygiene(long newVal)
	{
		hygiene=newVal;
	}

	@Override
	public boolean adjHygiene(long byThisMuch)
	{
		hygiene+=byThisMuch;
		if(hygiene<1)
		{
			hygiene=0;
			return false;
		}
		return true;
	}

	// Acct Expire Code
	@Override
	public long getAccountExpiration()
	{
		return  (account != null) ? account.getAccountExpiration() : accountExpires;
	}
	@Override
	public void setAccountExpiration(long newVal)
	{
		if(account != null)
			account.setAccountExpiration(newVal);
		accountExpires=newVal;
	}

	@Override
	public boolean addRoomVisit(Room R)
	{
		if((!CMSecurity.isDisabled(CMSecurity.DisFlag.ROOMVISITS))
		&&(R!=null)
		&&(!CMath.bset(R.phyStats().sensesMask(),PhyStats.SENSE_ROOMUNEXPLORABLE))
		&&(!(R.getArea() instanceof AutoGenArea))
		&&(R.getArea()!=null)
		&&(!hasVisited(R)))
		{
			roomSet().add(CMLib.map().getExtendedRoomID(R));
			return true;
		}
		return false;
	}
	@Override
	public boolean hasVisited(Room R)
	{
		return roomSet().contains(CMLib.map().getExtendedRoomID(R));
	}

	@Override
	public boolean hasVisited(Area A)
	{
		final int numRooms=A.getAreaIStats()[Area.Stats.VISITABLE_ROOMS.ordinal()];
		if(numRooms<=0)
			return true;
		return roomSet().roomCount(A.Name())>0;
	}

	@Override
	public void unVisit(Room R)
	{
		if(roomSet().contains(CMLib.map().getExtendedRoomID(R)))
			roomSet().remove(CMLib.map().getExtendedRoomID(R));
	}

	@Override
	public void unVisit(Area A)
	{
		Room R;
		for(final Enumeration<Room> r=A.getCompleteMap();r.hasMoreElements();)
		{
			R=r.nextElement();
			if(roomSet().contains(CMLib.map().getExtendedRoomID(R)))
				roomSet().remove(CMLib.map().getExtendedRoomID(R));
		}
	}

	@Override
	public int percentVisited(MOB mob, Area A)
	{
		if(A==null)
		{
			long totalRooms=0;
			long totalVisits=0;
			for(final Enumeration<Area> e=CMLib.map().areas();e.hasMoreElements();)
			{
				A=e.nextElement();
				if((CMLib.flags().canAccess(mob,A))
				&&(!CMath.bset(A.flags(),Area.FLAG_INSTANCE_CHILD)))
				{
					final int[] stats=A.getAreaIStats();
					if(stats[Area.Stats.VISITABLE_ROOMS.ordinal()]>0)
					{
						totalRooms+=stats[Area.Stats.VISITABLE_ROOMS.ordinal()];
						totalVisits+=roomSet().roomCount(A.Name());
					}
				}
			}
			if(totalRooms==0)
				return 100;
			final double pct=CMath.div(totalVisits,totalRooms);
			return (int)Math.round(100.0*pct);
		}
		final int numRooms=A.getAreaIStats()[Area.Stats.VISITABLE_ROOMS.ordinal()];
		if(numRooms<=0)
			return 100;
		final double pct=CMath.div(roomSet().roomCount(A.Name()),numRooms);
		return (int)Math.round(100.0*pct);
	}

	@Override
	public long leveledDateTime(int level)
	{
		if(levelInfo.size()==0)
			levelInfo.add(Integer.valueOf(0),Long.valueOf(System.currentTimeMillis()),"");
		long lowest=levelInfo.elementAtSecond(0).longValue();
		for(int l=1;l<levelInfo.size();l++)
		{
			if(level<levelInfo.elementAtFirst(l).intValue())
				return lowest;
			lowest=levelInfo.elementAtSecond(l).longValue();
		}
		return lowest;
	}

	@Override
	public void setLeveledDateTime(int level, Room R)
	{
		if(levelInfo.size()==0)
			levelInfo.add(Integer.valueOf(0),Long.valueOf(System.currentTimeMillis()),"");
		long lastTime=0;
		for(int l=0;l<levelInfo.size();l++)
		{
			final Triad<Integer, Long, String> triad = levelInfo.elementAt(l);
			if(level==triad.first.intValue())
			{
				triad.second = Long.valueOf(System.currentTimeMillis());
				triad.third = CMLib.map().getExtendedRoomID(R);
				return;
			}
			else
			if((System.currentTimeMillis()-lastTime)<TimeManager.MILI_SECOND)
				return;
			else
			if(level<triad.first.intValue())
			{
				levelInfo.insertElementAt(new Triad<Integer,Long,String>(Integer.valueOf(level),Long.valueOf(System.currentTimeMillis()),CMLib.map().getExtendedRoomID(R)),l);
				return;
			}
			lastTime=triad.second.longValue();
		}
		if((System.currentTimeMillis()-lastTime)<TimeManager.MILI_SECOND)
			return;
		levelInfo.addElement(Integer.valueOf(level),Long.valueOf(System.currentTimeMillis()),CMLib.map().getExtendedRoomID(R));
	}

	@Override
	public int getTotalLegacyLevels()
	{
		int total=0;
		for(final Integer value : legacy.values())
			total+=value.intValue();
		return total;
	}

	@Override
	public void addLegacyLevel(String category)
	{
		final Integer level=legacy.get(category);
		if(level != null)
			legacy.put(category, Integer.valueOf(level.intValue()+1));
		else
			legacy.put(category, Integer.valueOf(1));
	}

	@Override
	public int getLegacyLevel(String category)
	{
		final Integer level=legacy.get(category);
		if(level != null)
			return level.intValue();
		return 0;
	}

	@Override
	public PlayerAccount getAccount()
	{
		return account;
	}

	@Override
	public void setAccount(PlayerAccount account)
	{
		this.account = account;
	}

	@Override
	public ItemCollection getExtItems()
	{
		return extItems;
	}

	protected static String[] CODES={"CLASS","FRIENDS","IGNORE","TITLES",
									 "ALIAS","LASTIP","LASTDATETIME",
									 "CHANNELMASK",
									 "COLORSTR","PROMPT","POOFIN",
									 "POOFOUT","TRANPOOFIN","TRAINPOOFOUT",
									 "ANNOUNCEMSG","NOTES","WRAP","BIRTHDAY",
									 "ACCTEXPIRATION","INTRODUCTIONS","PAGEBREAK",
									 "SAVEDPOSE","THEME", "LEGLEVELS"};
	@Override
	public String getStat(String code)
	{
		switch(getCodeNum(code))
		{
		case 0: return ID();
		case 1: return getPrivateList(getFriends());
		case 2: return getPrivateList(getIgnored());
		case 3: return getTitleXML();
		case 4: return getAliasXML();
		case 5: return lastIP;
		case 6: return ""+lLastDateTime;
		case 7: return ""+channelMask;
		case 8: return colorStr;
		case 9: return prompt;
		case 10: return poofin;
		case 11: return poofout;
		case 12: return tranpoofin;
		case 13: return tranpoofout;
		case 14: return announceMsg;
		case 15: return notes;
		case 16: return ""+wrap;
		case 17: return CMParms.toStringList(birthday);
		case 18: return ""+accountExpires;
		case 19: return getPrivateList(introductions);
		case 20: return ""+pageBreak;
		case 21: return ""+savedPose;
		case 22: return ""+theme;
		case 23: return ""+getTotalLegacyLevels();
		default:
			return CMProps.getStatCodeExtensionValue(getStatCodes(), xtraValues, code);
		}
	}
	@Override
	public void setStat(String code, String val)
	{
		switch(getCodeNum(code))
		{
		case 0: break;
		case 1: { friends.clear(); friends.addAll(getHashFrom(val)); break; }
		case 2: { ignored.clear(); ignored.addAll(getHashFrom(val)); break; }
		case 3: setTitleXML(CMLib.xml().parseAllXML(val)); break;
		case 4: setAliasXML(CMLib.xml().parseAllXML(val)); break;
		case 5: lastIP=val; break;
		case 6: lLastDateTime=CMath.s_long(val); break;
		case 7: channelMask=CMath.s_int(val); break;
		case 8: colorStr=val; break;
		case 9: prompt=val; break;
		case 10: poofin=val; break;
		case 11: poofout=val; break;
		case 12: tranpoofin=val; break;
		case 13: tranpoofout=val; break;
		case 14: announceMsg=val; break;
		case 15: notes=val; break;
		case 16: setWrap(CMath.s_int(val)); break;
		case 17: setBirthday(val); break;
		case 18: accountExpires=CMath.s_long(val); break;
		case 19: { introductions.clear(); introductions.addAll(getHashFrom(val)); break; }
		case 20: pageBreak=CMath.s_int(val); break;
		case 21: savedPose=val; break;
		case 22: theme=CMath.s_int(val); break;
		case 23: break; // legacy levels
		default:
			CMProps.setStatCodeExtensionValue(getStatCodes(), xtraValues, code, val);
			break;
		}
	}
	@Override public int getSaveStatIndex(){return (xtraValues==null)?getStatCodes().length:getStatCodes().length-xtraValues.length;}
	private static String[] codes=null;
	@Override
	public String[] getStatCodes()
	{
		if(codes==null)
			codes=CMProps.getStatCodesList(CODES,this);
		return codes;
	}
	@Override public boolean isStat(String code){ return CMParms.indexOf(getStatCodes(),code.toUpperCase().trim())>=0;}
	protected int getCodeNum(String code)
	{
		for(int i=0;i<CODES.length;i++)
			if(code.equalsIgnoreCase(CODES[i]))
				return i;
		return -1;
	}
	@Override
	public boolean sameAs(PlayerStats E)
	{
		if(!(E instanceof DefaultPlayerStats))
			return false;
		for(int i=0;i<getStatCodes().length;i++)
			if(!E.getStat(getStatCodes()[i]).equals(getStat(getStatCodes()[i])))
				return false;
		return true;
	}

	@Override public int compareTo(CMObject o){ return CMClass.classID(this).compareToIgnoreCase(CMClass.classID(o));}
}