protected override void EmitWrite(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom)
        {
			if (arrayType.GetArrayRank() > 1)
			{
				return;
			}

            // int i and T[] arr
            using (Compiler.Local arr = ctx.GetLocalWithValue(arrayType, valueFrom))
			using (Compiler.Local len = new Compiler.Local(ctx, typeof(int)))
            using (Compiler.Local i = new ProtoBuf.Compiler.Local(ctx, typeof(int)))
			using (Compiler.Local writeObject = new Compiler.Local(ctx, typeof(bool)))
            {
				// int len = arr.Count;
				ctx.LoadValue(arr);
				ctx.LoadValue(arrayType.GetProperty("Length"));
				ctx.StoreValue(len);

				// writeObject = true;
				ctx.LoadValue(true);
				ctx.StoreValue(writeObject);

                bool writePacked = (options & OPTIONS_WritePacked) != 0;
                using (Compiler.Local token = writePacked ? new Compiler.Local(ctx, typeof(SubItemToken)) : null)
                {
                    if (writePacked)
                    {
                        ctx.LoadValue(fieldNumber);
                        ctx.LoadValue((int)WireType.String);
                        ctx.LoadReaderWriter();
                        ctx.EmitCall(typeof(ProtoWriter).GetMethod("WriteFieldHeader"));

                        ctx.LoadValue(arr);
                        ctx.LoadReaderWriter();
                        ctx.EmitCall(typeof(ProtoWriter).GetMethod("StartSubItem"));
                        ctx.StoreValue(token);

                        ctx.LoadValue(fieldNumber);
                        ctx.LoadReaderWriter();
                        ctx.EmitCall(typeof(ProtoWriter).GetMethod("SetPackedField"));
                    }
                    else
                    {
                    	ctx.LoadValue(fieldNumber);
						ctx.LoadValue((int)WireType.Variant);
						ctx.LoadReaderWriter();
						ctx.EmitCall(typeof(ProtoWriter).GetMethod("WriteFieldHeader"));

						if (AsReference)
						{
							using (Compiler.Local existing = new Compiler.Local(ctx, typeof(bool)))
							using (Compiler.Local objectKey = new Compiler.Local(ctx, typeof(int)))
							{
								//int objectKey = dest.NetCache.AddObjectKey(value, out existing);
								ctx.LoadReaderWriter();
								ctx.LoadValue(typeof(ProtoWriter).GetProperty("NetCache")); //dest.NetCache
								ctx.LoadValue(arr);
								ctx.LoadAddress(existing, typeof(bool));
								ctx.EmitCall(typeof(NetObjectCache).GetMethod("AddObjectKey", new Type[] { typeof(object), typeof(bool).MakeByRefType() }));
								ctx.StoreValue(objectKey);

								//writeObject = !existing;
								ctx.LoadValue(existing);

								Compiler.CodeLabel @writeBoolean = ctx.DefineLabel();
								Compiler.CodeLabel @trueCase = ctx.DefineLabel();

								ctx.BranchIfTrue(@trueCase, true);
								ctx.LoadValue(true);
								ctx.Branch(@writeBoolean, true);
								ctx.MarkLabel(@trueCase);
								ctx.LoadValue(false);
								ctx.MarkLabel(@writeBoolean);
								
								ctx.StoreValue(writeObject);

								//ProtoWriter.WriteUInt32(existing ? (uint)objectKey : 0, dest);
								using (Compiler.Local valueToWrite = new Compiler.Local(ctx, typeof(uint)))
								{
                                    ctx.LoadValue(0);
                                    ctx.StoreValue(valueToWrite);

									Compiler.CodeLabel @endValueWrite = ctx.DefineLabel();

									ctx.LoadValue(existing);
									ctx.BranchIfFalse(@endValueWrite, true);

									ctx.LoadValue(objectKey);
									ctx.CastToObject(typeof(uint));
									ctx.StoreValue(valueToWrite);

									ctx.MarkLabel(@endValueWrite);

									ctx.LoadValue(valueToWrite);
									ctx.LoadReaderWriter();
									ctx.EmitCall(typeof(ProtoWriter).GetMethod("WriteUInt32"));
								}
							}
						}
						else
						{
							// bool isEmpty = len == 0;
							// ProtoWriter.WriteBoolean(isEmpty, dest);
							ctx.LoadValue(len);
							ctx.LoadValue(0);
							ctx.TestEqual();
							ctx.LoadReaderWriter();
							ctx.EmitCall(typeof(ProtoWriter).GetMethod("WriteBoolean"));
						}
                    }

                	Compiler.CodeLabel @endWrite = ctx.DefineLabel();
                	ctx.LoadValue(writeObject);
                	ctx.BranchIfFalse(@endWrite, false);

                    EmitWriteArrayLoop(ctx, i, arr);

					ctx.MarkLabel(@endWrite);
						
                    if (writePacked)
                    {
                        ctx.LoadValue(token);
                        ctx.LoadReaderWriter();
                        ctx.EmitCall(typeof(ProtoWriter).GetMethod("EndSubItem"));
                    }
                }
            }
        }