protected override void GenerateConstructor(CodeConstructor constructor, CodeTypeDeclaration declaration)
		{	
			if (base.IsCurrentDelegate || base.IsCurrentEnum || base.IsCurrentInterface)
			{
				return;
			}
			this.OutputMemberAccessModifier(constructor.Attributes);
			base.Output.Write("this(");
			this.OutputParameters(constructor.Parameters);
			base.Output.Write(")");
			base.OutputStartBrace();
			base.Indent++;
			if (constructor.BaseConstructorArgs.Count > 0)
			{
				base.Output.Write("super(");
				this.OutputExpressionList(constructor.BaseConstructorArgs);
				base.Output.WriteLine(");");
			}
			if (constructor.ChainedConstructorArgs.Count > 0)
			{
				base.Output.Write("this(");
				this.OutputExpressionList(constructor.ChainedConstructorArgs);
				base.Output.WriteLine(");");
			}
			base.GenerateStatements(constructor.Statements);
			base.Indent--;
			base.Output.WriteLine('}');
		}
		public void WriteConstructors(CodeTypeDeclaration tdecl, string className)
		{
			if (ParentInstruction.LinesOfDocumentation.Count == 0)
			{
				ParentInstruction.LinesOfDocumentation.Add("Creates a new instance of the <see cref=\"" + ParentInstruction.FileName + "\" /> class.");
			}
			if (Arg1.ArgType == InstructionArgType.None)
			{
				CodeConstructor c = new CodeConstructor();
				c.Attributes = MemberAttributes.Public;

				c.Documentation.AddRange(
					new CodeDocumentationSummaryNode(ParentInstruction.LinesOfDocumentation),
					new CodeDocumentationParameterNode("parentAssembler", "The assembler to add this instruction to.")
				);
				c.Parameters.Add(new CodeParameterDeclarationExpression(StaticTypeReferences.Assembler, "parentAssembler"));
				c.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("parentAssembler"));
				tdecl.Members.Add(c);
			}
			else
			{
				List<byte> sizesNeeded = new List<byte>(4);
				List<string> formsNeeded = new List<string>(4);
				bool constructorNeeded;
				bool needsSizeArg = ParentInstruction.NeedsSizeArgument(Arg1.ArgType, Arg2.ArgType, Arg3.ArgType, ref sizesNeeded, out constructorNeeded, ref formsNeeded);
				if (constructorNeeded)
				{
					int segArgIdx;
					bool needsSegArg = NeedsSegment(out segArgIdx);
					CodeConstructor c = new CodeConstructor();
					c.Attributes = MemberAttributes.Public;
					c.Parameters.Add(new CodeParameterDeclarationExpression(StaticTypeReferences.Assembler, "parentAssembler"));
					c.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("parentAssembler"));
					Arg1.ArgType.RequestParameters(Arg1, needsSizeArg, c.Parameters);
					Arg2.ArgType.RequestParameters(Arg2, needsSizeArg, c.Parameters);
					Arg3.ArgType.RequestParameters(Arg3, needsSizeArg, c.Parameters);
					if (needsSizeArg)
						c.Parameters.Add(new CodeParameterDeclarationExpression(StaticTypeReferences.Byte, "size"));
					if (needsSegArg)
					{
						CodeParameterDeclarationExpression cpd = new CodeParameterDeclarationExpression(StaticTypeReferences.Segment, "segment");
						cpd.DefaultValueExpression = new CodeFieldReferenceExpression(StaticTypeReferences.SegmentExpression, DefaultSegment.ToString());
						c.Parameters.Add(cpd);
					}
						
					CodeDocumentationNodeCollection docs = new CodeDocumentationNodeCollection();
					docs.Add(new CodeDocumentationParameterNode("parentAssembler", "The assembler to add this instruction to."));
					Arg1.ArgType.AddDocumentationLines(Arg1.Name, docs);
					Arg2.ArgType.AddDocumentationLines(Arg2.Name, docs);
					Arg3.ArgType.AddDocumentationLines(Arg3.Name, docs);
					if (needsSizeArg)
						docs.Add(new CodeDocumentationParameterNode("size", "The size of the operands for this instruction."));
					if (needsSegArg)
						docs.Add(new CodeDocumentationParameterNode("segment", "The segment to use for memory access within this instruction."));
					c.Documentation.Add(new CodeDocumentationSummaryNode(ParentInstruction.LinesOfDocumentation));
					c.Documentation.AddRange(docs);
					WriteConstructorBodyInstructionFormDetermination(c, sizesNeeded, formsNeeded);
					Arg1.ArgType.WriteConstructorBodyArgProcessing(this, c, 0);
					Arg2.ArgType.WriteConstructorBodyArgProcessing(this, c, 1);
					Arg3.ArgType.WriteConstructorBodyArgProcessing(this, c, 2);
					if (needsSegArg)
					{
						c.Statements.Add(
							new CodeAssignStatement(
								new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), GetArgName(FieldTypeRegistry.Segment.ID, 1, segArgIdx)),
								new CodeArgumentReferenceExpression("segment")
							)
						);
					}

					tdecl.Members.Add(c);
				}
			}
		}
		private void WriteConstructorBodyInstructionFormDetermination(CodeConstructor c, List<byte> sizesNeeded, List<string> formsNeeded)
		{
			if (sizesNeeded.Count > 1)
			{
				CodeSwitchStatement s = new CodeSwitchStatement(new CodeArgumentReferenceExpression("size"));

				// If your willing to accept the sizes being out of order, then this isn't
				// needed, but I don't like them out of order so it is.
				List<KeyValuePair<byte, string>> sizeFormPairs = new List<KeyValuePair<byte, string>>();
				for (int i = 0; i < sizesNeeded.Count; i++)
				{
					sizeFormPairs.Add(new KeyValuePair<byte, string>(sizesNeeded[i], formsNeeded[i]));
				}
				sizeFormPairs.Sort(
					delegate(KeyValuePair<byte, string> x, KeyValuePair<byte, string> y)
					{
						return x.Key.CompareTo(y.Key);
					}
				);
				sizesNeeded.Sort();
				for (int i = 0; i < sizeFormPairs.Count; i++)
				{
					// The cast is needed so it doesn't write the value out as hex.
					CodeCaseStatement cas = new CodeCaseStatement(new CodePrimitiveExpression((int)sizeFormPairs[i].Key));
					cas.Statements.Add(
						new CodeAssignStatement(
							new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "InstructionForm"),
							new CodeFieldReferenceExpression(StaticTypeReferences.InstructionFormExpression, sizeFormPairs[i].Value)
						)
					);
					cas.Statements.Add(new CodeBreakStatement());
					s.Cases.Add(cas);
					InstructionFormEnumRegistry.RequestForm(sizeFormPairs[i].Value);
				}

				string exSzs = "";
				if (sizesNeeded.Count == 2)
				{
					exSzs = "either " + sizesNeeded[0].ToString() + " or " + sizesNeeded[1].ToString();
				}
				else
				{
					exSzs = sizesNeeded[0].ToString();
					int szndc = sizesNeeded.Count - 1;
					for (int i = 1; i < szndc; i++)
					{
						exSzs += ", " + sizesNeeded[i].ToString();
					}
					exSzs += " or " + sizesNeeded[szndc];
				}
				CodeDefaultCaseStatement defStat = new CodeDefaultCaseStatement();
				defStat.Statements.Add(
					new CodeThrowExceptionStatement(
						new CodeObjectCreateExpression(
							StaticTypeReferences.ArgumentOutOfRangeException, 
							new CodePrimitiveExpression("size"),
							new CodePrimitiveExpression("Invalid size! Expected " + exSzs + "!")
						)
					)
				);
				s.Cases.Add(defStat);

				c.Statements.Add(s);
			}
			else
			{
				if (ParentInstruction.FinalForms.Count > 1)
				{
					c.Statements.Add(
						new CodeAssignStatement(
							new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "InstructionForm"),
							new CodeFieldReferenceExpression(StaticTypeReferences.InstructionFormExpression, GetInstructionCaseString())
						)
					);
					InstructionFormEnumRegistry.RequestForm(GetInstructionCaseString());
				}
			}
		}
		public void WriteConstructorBodyArgProcessing(InstructionForm frm, CodeConstructor c, int argIdx)
		{
			InstructionArg arg = frm[argIdx];
			switch (ID)
			{
				case None_ID:
					break;
				// Dis8 & Dis16 have to be sign-extended before being stored.
				// (this way they can be compared using the exact same code as
				// dis32 can)
				case Dis8_ID:
				case Dis16_ID:
					c.Statements.Add(
						new CodeAssignStatement(
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(),
								frm.GetArgName(FieldTypeRegistry.UInt.ID, 1, argIdx)
							),
							new CodeCastExpression(
								StaticTypeReferences.UInt,
								new CodeCastExpression(
									StaticTypeReferences.Int,
									new CodeArgumentReferenceExpression(arg.Name + DisArgSuffix)
								)
							)
						)
					);
					break;
				// No sign extension needed.
				case Dis32_ID:
					c.Statements.Add(
						new CodeAssignStatement(
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(),
								frm.GetArgName(FieldTypeRegistry.UInt.ID, 1, argIdx)
							),
							new CodeCastExpression(
								StaticTypeReferences.UInt,
								new CodeArgumentReferenceExpression(arg.Name + DisArgSuffix)
							)
						)
					);
					break;
				case Imm8_ID:
				case Imm16_ID:
				case Imm32_ID:
					c.Statements.Add(
						new CodeAssignStatement(
							new CodeFieldReferenceExpression(
								new CodeThisReferenceExpression(),
								frm.GetArgName(FieldTypeRegistry.UInt.ID, 1, argIdx)
							),
							new CodeCastExpression(
								StaticTypeReferences.UInt,
								new CodeArgumentReferenceExpression(arg.Name + ImmArgSuffix)
							)
						)
					);
					break;

				default:
					int[] reqs = new int[FieldTypeRegistry.MaxFieldID + 1];
					foreach(CustomInstructionArgParameter p in mParameters.Values)
					{
						c.Statements.Add(
							new CodeAssignStatement(
								new CodeFieldReferenceExpression(
									new CodeThisReferenceExpression(),
									frm.GetArgName(p.ArgType, reqs[p.ArgType] + 1, argIdx)
								),
								new CodeArgumentReferenceExpression(arg.Name + p.ArgNameSuffix)
							)
						);
						reqs[p.ArgType]++;
					}
					break;
			}
		}