static public NetworkModel DecodeToNetworkModel(NeatGenome.NeatGenome g)
		{
			ModelNeuronList masterNeuronList = new ModelNeuronList();

			// loop all neurons and build a table keyed on id.
			HybridDictionary neuronTable = new HybridDictionary(g.NeuronGeneList.Count);
			foreach(NeuronGene neuronGene in g.NeuronGeneList)
			{
				ModelNeuron modelNeuron = new ModelNeuron(neuronGene.NeuronType, neuronGene.InnovationId,neuronGene.ActivationFunction);
				neuronTable.Add(modelNeuron.Id, modelNeuron);
				masterNeuronList.Add(modelNeuron);
			}

			// Loop through all of the connections.
			// Now we have a neuron table keyed on id we can attach the connections
			// to their source and target neurons.
			foreach(ConnectionGene connectionGene in g.ConnectionGeneList)
			{
				ModelConnection modelConnection = new ModelConnection();
				modelConnection.Weight = connectionGene.Weight;
				modelConnection.SourceNeuron = (ModelNeuron)neuronTable[connectionGene.SourceNeuronId];
				modelConnection.TargetNeuron = (ModelNeuron)neuronTable[connectionGene.TargetNeuronId];

				modelConnection.SourceNeuron.OutConnectionList.Add(modelConnection);
				modelConnection.TargetNeuron.InConnectionList.Add(modelConnection);
			}

            //Sebastian. Build Model connections
            foreach (ModuleGene mg in g.ModuleGeneList)
            {
                foreach (uint sourceID in mg.InputIds)
                {
                    foreach (uint targetID in mg.OutputIds)
                    {
                        ModelConnection modelConnection = new ModelConnection();
                        modelConnection.Weight = 1.0; //TODO  connectionGene.Weight;
                        modelConnection.SourceNeuron = (ModelNeuron)neuronTable[sourceID];
                        modelConnection.TargetNeuron = (ModelNeuron)neuronTable[targetID];

                        modelConnection.SourceNeuron.OutConnectionList.Add(modelConnection);
                        modelConnection.TargetNeuron.InConnectionList.Add(modelConnection);
                    }
                }
            }

			return new NetworkModel(masterNeuronList);
		}
		static public NetworkModel DecodeToNetworkModel(ConcurrentNetwork network)
		{
			ModelNeuronList masterNeuronList = new ModelNeuronList();
			
			// loop all neurons and build a table keyed on id.
			Hashtable neuronTable = new Hashtable(network.MasterNeuronList.Count);
			foreach(Neuron neuron in network.MasterNeuronList)
			{	
				ModelNeuron modelNeuron = new ModelNeuron(neuron.NeuronType, neuron.Id,ActivationFunctionFactory.GetActivationFunction("NullFn"));
				neuronTable.Add(modelNeuron.Id, modelNeuron);
				masterNeuronList.Add(modelNeuron);
			}

			// Loop through all of the connections (within the neurons)
			// Now we have a neuron table keyed on id we can attach the connections
			// to their source and target neurons.
			foreach(Neuron neuron in network.MasterNeuronList)
			{
				foreach(Connection connection in neuron.ConnectionList)
				{
					ModelConnection modelConnection = new ModelConnection();
					modelConnection.Weight = connection.Weight;
					modelConnection.SourceNeuron = (ModelNeuron)neuronTable[connection.SourceNeuronId];
					modelConnection.TargetNeuron = (ModelNeuron)neuronTable[connection.TargetNeuronId];

					modelConnection.SourceNeuron.OutConnectionList.Add(modelConnection);
					modelConnection.TargetNeuron.InConnectionList.Add(modelConnection);
				}
			}

			return new NetworkModel(masterNeuronList);
		}
		private void PaintNeuron(Graphics g, ModelNeuron neuron)
		{
			Point neuronPos = DocToViewport(neuron.Position);
			// Is the neuron within the viewport area?
			if(!IsPointWithinViewport(neuronPos))
			{	// Don't waste time painting this neuron.
				return;
			}

			Point p = new Point(neuronPos.X-neuronDiameterHalfed, neuronPos.Y-neuronDiameterHalfed);
			Size s = new Size(neuronDiameter, neuronDiameter);
			Rectangle r = new Rectangle(p,s);
            Brush b;
			//g.FillEllipse(brushNeuron, r);
            if (neuron.ActivationFunction == NeuralNetwork.ActivationFunctionFactory.GetActivationFunction("Gaussian"))
                b = brushNeuronGaussian;
            else if (neuron.ActivationFunction == NeuralNetwork.ActivationFunctionFactory.GetActivationFunction("Linear"))
                b = brushNeuronLinear;
            else if (neuron.ActivationFunction == NeuralNetwork.ActivationFunctionFactory.GetActivationFunction("BipolarSigmoid"))
                b = brushNeuronSigmoid;
            else if (neuron.ActivationFunction == NeuralNetwork.ActivationFunctionFactory.GetActivationFunction("Sine"))
                b = brushNeuronSine;
            else
                b = brushNeuronCore;
			g.FillRectangle(b, r);
			g.DrawRectangle(penBlack, r);

			// Draw the neuron ID.
			neuronPos.X += neuronDiameterHalfed+1;
			neuronPos.Y -= neuronDiameterHalfed/2;
			g.DrawString(neuron.Id.ToString(), fontNeuronId, brushBlack, neuronPos);
		}
		private void PaintNeuron(Graphics g, ModelNeuron neuron)
		{
			Point neuronPos = DocToViewport(neuron.Position);
			// Is the neuron within the viewport area?
			if(!IsPointWithinViewport(neuronPos))
			{	// Don't waste time painting this neuron.
				return;
			}

			Point p = new Point(neuronPos.X-neuronDiameterHalfed, neuronPos.Y-neuronDiameterHalfed);
			Size s = new Size(neuronDiameter, neuronDiameter);
			Rectangle r = new Rectangle(p,s);

			//g.FillEllipse(brushNeuron, r);
			g.FillRectangle(brushNeuronCore, r);
			g.DrawRectangle(penBlack, r);

			// Draw the neuron ID.
			neuronPos.X += neuronDiameterHalfed+1;
			neuronPos.Y -= neuronDiameterHalfed/2;
			g.DrawString(neuron.Id.ToString(), fontNeuronId, brushBlack, neuronPos);
		}
		private void UpdateModelBounds(ModelNeuron neuron)
		{
			if(neuron.Position.X > bounds.Width)
				bounds.Width = neuron.Position.X;

			if(neuron.Position.Y > bounds.Height)
				bounds.Height = neuron.Position.Y;
		}