// constructor also goes here
        private EvmByteCode WrapByteCode(EvmByteCode toWrap)
        {
            var preAssembly = new EthSharpAssembly();

            preAssembly.Append(toWrap.ByteCode.Count);   // push length of bytecode
            preAssembly.Append(0x0c);                    // push offset of bytecode - TODO: THIS COULD CHANGE IF THIS BLOCK CHANGES!
            preAssembly.Append(UInt256.Zero);            // push memory location to store in (0)
            preAssembly.Append(EvmInstruction.CODECOPY); // codecopy
            preAssembly.Append(toWrap.ByteCode.Count);   // push length of code to pick
            preAssembly.Append(UInt256.Zero);            // push location of code (0)
            preAssembly.Append(EvmInstruction.RETURN);
            var preByteCode = preAssembly.Assemble();

            toWrap.ByteCode.InsertRange(0, preByteCode.ByteCode);
            return(toWrap);
        }
        public EvmByteCode Assemble()
        {
            EvmByteCode ret = new EvmByteCode();

            Dictionary <int, List <int> > jumpFromLocations = new Dictionary <int, List <int> >();
            Dictionary <int, int>         tagLocations      = new Dictionary <int, int>();

            foreach (var item in Items)
            {
                switch (item.Type)
                {
                case AssemblyItemType.Operation:
                    ret.ByteCode.Add((byte)item.Instruction);
                    break;

                case AssemblyItemType.Push:
                {
                    int length = item.Data.ByteLength;
                    var sizedPushInstruction = EvmInstruction.PUSH1 - 1 + length;

                    ret.ByteCode.Add((byte)sizedPushInstruction);
                    ret.ByteCode.AddRange(item.Data.ToByteArrayBE().Skip(32 - length).Take(length));
                    break;
                }

                case AssemblyItemType.PushTag:
                {
                    ret.ByteCode.Add((byte)EvmInstruction.PUSH1);
                    if (jumpFromLocations.ContainsKey(item.Data.ToInt()))
                    {
                        jumpFromLocations[item.Data.ToInt()].Add(ret.ByteCode.Count);
                    }
                    else
                    {
                        jumpFromLocations[item.Data.ToInt()] = new List <int> {
                            ret.ByteCode.Count
                        };
                    }
                    ret.ByteCode.Add((byte)0);      //This will get replaced with the location to jump to!
                    break;
                }

                case AssemblyItemType.Tag:
                    tagLocations.Add(item.Data.ToInt(), ret.ByteCode.Count);
                    ret.ByteCode.Add((byte)EvmInstruction.JUMPDEST);
                    break;
                }
            }

            //Update all jumps to correct location
            foreach (var tag in tagLocations)
            {
                int tagId       = tag.Key;
                int tagLocation = tag.Value;
                foreach (var jumpFrom in jumpFromLocations[tagId])
                {
                    ret.ByteCode[jumpFrom] = (byte)tagLocation;
                }
            }

            return(ret);
        }