public FunctionGraphicsArray(
            CircuitState circuitState,
            int[] address,
            int[] inputData,
            int[] outputData,
            int write,
            IEnumerable <CircuitSymbol> symbols
            ) : base(circuitState, FunctionMemory.Input(address, null, inputData, write), outputData)
        {
            this.circuitSymbol = symbols.ToList();
            Tracer.Assert(0 < this.circuitSymbol.Count);

            GraphicsArray graphicsArray = (GraphicsArray)this.circuitSymbol[0].Circuit;

            this.project = graphicsArray.CircuitProject.ProjectSet.Project;

            this.address   = address;
            this.inputData = inputData;
            this.write     = write;
            this.writeOn   = graphicsArray.WriteOn1 ? State.On1 : State.On0;

            Tracer.Assert(this.inputData.Length == outputData.Length && this.inputData.Length == graphicsArray.DataBitWidth);

            this.bitsPerPixel = graphicsArray.BitsPerPixel;
            this.drawingRect  = new Int32Rect(0, 0, graphicsArray.Width, graphicsArray.Height);

            int w = this.drawingRect.Width * this.bitsPerPixel;

            this.memoryStride = w / this.DataBitWidth + (((w % this.DataBitWidth) == 0) ? 0 : 1);
            int byteStride = w / 8 + (((w % 8) == 0) ? 0 : 1);

            this.bitmapStride = Math.Max(byteStride * 8, this.memoryStride * this.DataBitWidth) / 8;
            Tracer.Assert(this.memoryStride * this.DataBitWidth <= this.bitmapStride * 8);
            this.zoom = graphicsArray.Zoom;

            switch (graphicsArray.OnStart)
            {
            case MemoryOnStart.Random:
                this.data = this.Allocate();
                circuitState.Random.NextBytes(this.data);
                break;

            case MemoryOnStart.Zeros:
                this.data = this.Allocate();
                break;

            case MemoryOnStart.Ones:
                this.data = this.Allocate();
                for (int i = 0; i < this.data.Length; i++)
                {
                    this.data[i] = 0xFF;
                }
                break;

            case MemoryOnStart.Data:
            default:
                Tracer.Fail();
                break;
            }
        }
        protected FunctionMemory(
            CircuitState circuitState, int[] address, int[] inputData, int[] outputData, int[] address2, int[] outputData2, int write, Memory memory
            ) : base(circuitState, FunctionMemory.Input(address, address2, inputData, write), FunctionMemory.Output(outputData, outputData2))
        {
            this.address     = address;
            this.address2    = address2;
            this.inputData   = inputData;
            this.outputData  = outputData;
            this.outputData2 = outputData2;
            this.Memory      = memory;
            if (inputData != null)
            {
                Tracer.Assert(memory.Writable);
                Tracer.Assert(this.inputData.Length == this.outputData.Length);
                this.write   = write;
                this.writeOn = this.Memory.WriteOn1 ? State.On1 : State.On0;
                switch (this.Memory.OnStart)
                {
                case MemoryOnStart.Random:
                    this.data = this.Allocate();
                    circuitState.Random.NextBytes(this.data);
                    break;

                case MemoryOnStart.Zeros:
                    this.data = this.Allocate();
                    break;

                case MemoryOnStart.Ones:
                    this.data = this.Allocate();
                    for (int i = 0; i < this.data.Length; i++)
                    {
                        this.data[i] = 0xFF;
                    }
                    break;

                case MemoryOnStart.Data:
                    this.data = memory.MemoryValue();
                    break;

                default:
                    Tracer.Fail();
                    break;
                }
            }
            else
            {
                Tracer.Assert(!memory.Writable);
                this.write = -1;
                this.data  = memory.MemoryValue();
            }
        }