public override void Visit(CodePoint expression)
		{
			terminal.Peek().Append(expression.Match);
		}
		public override void Visit(CodePoint expression)
		{
			String matchtext = expression.Match;

			_matchStack.Push(
				delegate(IInputIterator iterator)
				{
					if (matchtext.StartsWith("#x"))
					{
						//hexadecimal evaluation
						String hexinput = matchtext.Substring(2);
						if (hexinput == String.Empty)
							throw new ArgumentException("Hex value specified is empty.");
						if (hexinput.Length % 2 != 0)
							hexinput = "0" + hexinput; // on incomplete byte boundaries shift right

						int total_compare_bytes = hexinput.Length / 2;

						for (int i = 0; i < total_compare_bytes; i++)
						{
							if (iterator.Current() == -1)
								return false;

							var compareWith = (Byte)iterator.Current();

							for (Int32 j = 0; j < 2; j++)
							{
								// low nibble comparison
								Int32 nibbleOffset = 0;
								if (j == 0)
								{
									// high nibble comparison
									nibbleOffset = 4;
								}

								// j == 0 == high nibble
								// j == 1 == low nibble
								var tmp = (Byte)hexinput[i * 2 + j];
								if (tmp >= (Byte)'0' && tmp <= (Byte)'9')
								{
									tmp = (Byte)((tmp - (Byte)'0') << nibbleOffset);
								}
								else if (tmp >= (Byte)'a' && tmp <= (Byte)'f')
								{
									tmp = (Byte)((tmp - (Byte)'A' + 10) << nibbleOffset);
								}
								else if (tmp >= (Byte)'A' && tmp <= (Byte)'F')
								{
									tmp = (Byte)((tmp - (Byte)'A' + 10) << nibbleOffset);
								}
								else if (tmp == (Byte)'x' || tmp == (Byte)'X')
								{
									// don't care ignore nibble comparison
								}
								else
								{
									throw new ArgumentException("Hex value specified contains invalid characters.");
								}

								if (!(tmp == (Byte)'x' || tmp == (Byte)'X'))
								{
									if (
										((compareWith & (1 << (nibbleOffset + 3))) >> (nibbleOffset + 3)) !=
										((tmp & (1 << (nibbleOffset + 3))) >> (nibbleOffset + 3)) ||
										((compareWith & (1 << (nibbleOffset + 2))) >> (nibbleOffset + 2)) !=
										((tmp & (1 << (nibbleOffset + 2))) >> (nibbleOffset + 2)) ||
										((compareWith & (1 << (nibbleOffset + 1))) >> (nibbleOffset + 1)) !=
										((tmp & (1 << (nibbleOffset + 1))) >> (nibbleOffset + 1)) ||
										((compareWith & (1 << nibbleOffset)) >> nibbleOffset) !=
										((tmp & (1 << nibbleOffset)) >> nibbleOffset)
										)
									{
										return false;
									}
								}
							}

							iterator.Next();
						}
					}
					else if (matchtext.StartsWith("#b"))
					{
						// binary evaluation
						String binaryinput = matchtext.Substring(2);
						if (binaryinput == String.Empty)
							throw new ArgumentException("Binary value specified is empty.");
						if (binaryinput.Length % 8 != 0)
							binaryinput = "".PadLeft(8 - (binaryinput.Length % 8), '0') + binaryinput;
						// on incomplete byte boundaries shift right

						int total_compare_bytes = binaryinput.Length / 8;

						for (int i = 0; i < total_compare_bytes; i++)
						{
							if (iterator.Current() == -1)
								return false;

							var compareWith = (Byte)iterator.Current();
							for (Int32 j = 0; j < 8; j++)
							{
								var tmp = (Byte)binaryinput[i * 8 + j];
								if (tmp == (Byte)'0')
								{
									tmp = 0x00;
								}
								else if (tmp == (Byte)'1')
								{
									tmp = 0x01;
								}
								else if (tmp == (Byte)'x' || tmp == (Byte)'X')
								{
									// don't care ignore nibble comparison
								}
								else
								{
									throw new ArgumentException(
										"Binary value specified contains invalid characters.");
								}

								if (!(tmp == (Byte)'x' || tmp == (Byte)'X'))
								{
									Int32 bit2compare = 7 - j;
									if (
										((compareWith & (1 << bit2compare)) >> bit2compare) != tmp
										)
									{
										return false;
									}
								}
							}

							iterator.Next();
						}
					}
					else
					{
						// decimal codepoint evaluation
						String decimalinput = matchtext.Substring(1);
						if (decimalinput == String.Empty)
							throw new ArgumentException("Decimal codepoint value specified is empty.");
						if (!Regex.IsMatch(decimalinput, @"^[0-9]+$"))
							throw new ArgumentException(
								"Decimal codepoint value specified contains invalid characters.");
						if (decimalinput.Length > 10) // 4,294,967,295
							throw new ArgumentException(
								"Decimal codepoint value exceeds 4 byte maximum length.  Largest decimal value possible 2^32");

						UInt32 codepoint = UInt32.Parse(decimalinput);
						var c4 = (Byte)(codepoint >> 24);
						var c3 = (Byte)(codepoint >> 16);
						var c2 = (Byte)(codepoint >> 8);
						var c1 = (Byte)(codepoint);
						if (c4 != 0x00)
						{
							// consumes 4 bytes
							if (iterator.Current() == -1 || iterator.Current() != c1)
							{
								return false;
							}
							iterator.Next();
							if (iterator.Current() == -1 || iterator.Current() != c2)
							{
								return false;
							}
							iterator.Next();
							if (iterator.Current() == -1 || iterator.Current() != c3)
							{
								return false;
							}
							iterator.Next();
							if (iterator.Current() == -1 || iterator.Current() != c4)
							{
								return false;
							}
							iterator.Next();
						}
						else if (c3 != 0x00)
						{
							// consumes 3 bytes
							if (iterator.Current() == -1 || iterator.Current() != c1)
							{
								return false;
							}
							iterator.Next();
							if (iterator.Current() == -1 || iterator.Current() != c2)
							{
								return false;
							}
							iterator.Next();
							if (iterator.Current() == -1 || iterator.Current() != c3)
							{
								return false;
							}
							iterator.Next();
						}
						else if (c2 != 0x00)
						{
							// consumes 2 bytes
							if (iterator.Current() == -1 || iterator.Current() != c1)
							{
								return false;
							}
							iterator.Next();
							if (iterator.Current() == -1 || iterator.Current() != c2)
							{
								return false;
							}
							iterator.Next();
						}
						else
						{
							// user must want to match null \0
							// (c1 != 0x00)
							// consumes 1 byte
							if (iterator.Current() == -1 || iterator.Current() != c1)
							{
								return false;
							}
							iterator.Next();
						}
					}

					return true;
				}
				);
		}
 public abstract void Visit(CodePoint expression);