private void ConnectTerminals(Connection connection, Circuit circuit, Dictionary <BaseElement, BaseElementData> elemDict)
 {
     foreach (BaseElement be in circuit)
     {
         if (be is InputOutputElement == false)
         {
             continue;
         }
         BaseElementData elemData = elemDict[be];
         if (elemData == null)
         {
             continue;
         }
         InputOutputElement io = be as InputOutputElement;
         if (elemData is IOElementData)
         {
             IOElementData ioelemData = elemData as IOElementData;
             ProcessTerminalList(ioelemData.Inputs, io.Inputs, connection);
             ProcessTerminalList(ioelemData.Outputs, io.Outputs, connection);
         }
         if (elemData is InputElementData)
         {
             InputElementData ioelemData = elemData as InputElementData;
             ProcessTerminalList(ioelemData.Outputs, io.Outputs, connection);
         }
         else if (elemData is ConstantInputData)
         {
             ConstantInputData ioelemData = elemData as ConstantInputData;
             ProcessTerminalList(ioelemData.Outputs, io.Outputs, connection);
         }
         if (elemData is ClockData)
         {
             ClockData ioelemData = elemData as ClockData;
             ProcessTerminalList(ioelemData.Outputs, io.Outputs, connection);
         }
         if (elemData is OutputElementData)
         {
             OutputElementData ioelemData = elemData as OutputElementData;
             ProcessTerminalList(ioelemData.Inputs, io.Inputs, connection);
         }
     }
 }
        //private Connection ConvertConnectionData(ConnectionData connectionData) //directly done in CreateElements()
        //{
        //    Connection connection = new Connection();
        //    connection.Name = connectionData.Name;
        //    return connection;
        //}

        private InputOutputElement ConvertElementData(BaseElementData elemData, bool createGraphics,
                                                      Dictionary <BaseElement, BaseElementData> elemDict, SignalList signals)
        {
            InputOutputElement io = null;
            //determine type
            string desiredType = String.Empty;

            if (elemData is ClockData)
            {
                desiredType = typeof(Clock).Name;
            }
            if (elemData is ConstantInputData)
            {
                desiredType = typeof(ConstantInput).Name;
            }
            if (elemData is InputElementData)
            {
                desiredType = typeof(SignalInput).Name;
            }
            if (elemData is OutputElementData)
            {
                desiredType = typeof(SignalOutput).Name;
            }
            if (elemData is IOElementData)
            {
                desiredType = (elemData as IOElementData).Type;
            }
            if (elemData is MacroElementData)
            {
                desiredType = typeof(Macro).Name;
                MacroCache       cache            = MacroCache.Instance;
                MacroElementData macroElementData = elemData as MacroElementData;
                io = cache.GetMacro(macroElementData.Type);
                if (io == null)
                {
                    string loaded = cache.LoadMacro(macroElementData.Reference);
                    if (String.IsNullOrEmpty(loaded))
                    {
                        throw new MacroReferenceNotFoundException(String.Format("Macro not found: \"{0}\".", macroElementData.Type));
                    }
                    else if (loaded.CompareTo(macroElementData.Type) != 0)
                    {
                        throw new MacroReferenceTypeMismatchException(String.Format("Desired macro type \"{0}\" mismatches type \"{1}\" contained in file \"{2}\".", macroElementData.Type, loaded, macroElementData.Reference));
                    }
                    io = cache.GetMacro(macroElementData.Type);
                }
                if (createGraphics)
                {
                    GraphicBaseElement graphic = GraphicObjectFactory.CreateInstance(typeof(Macro), io);
                    graphic.Location = new PointF(elemData.X, elemData.Y);
                }
            }
            if (String.IsNullOrEmpty(desiredType))
            {
                throw new NotImplementedException(String.Format("Restoring of Type {0} not implemented", elemData.GetType().Name));
                //return null;
            }
            //create instance of io element type type (not macros)
            foreach (Type type in m_ElementTypes)
            {
                if (type.Name.Equals(desiredType))
                {
                    io = (InputOutputElement)Activator.CreateInstance(type);

                    if (elemData is InputElementData)
                    {
                        InputElementData inelemData = elemData as InputElementData;
                        if (signals != null)
                        {
                            foreach (Signal signal in signals)
                            {
                                if (signal.Name.Equals(inelemData.SignalName))
                                {
                                    (io as SignalInput).Signal = signal;
                                }
                            }
                        }
                    }

                    if (createGraphics)
                    {
                        GraphicBaseElement graphic = GraphicObjectFactory.CreateInstance(type, io);
                        graphic.Location = new PointF(elemData.X, elemData.Y);
                    }
                    break;
                }
            }
            if (io == null)
            {
                return(null);
            }
            //restore terminals
            if (elemData is ClockData)
            {
                ClockData clockData = elemData as ClockData;
                io.OutputCount = clockData.Outputs.Length;
                RestoreTerminals(clockData.Outputs, io.Outputs);
                Clock clock = io as Clock;
                clock.HighDuration = clockData.HighDuration;
                clock.LowDuration  = clockData.LowDuration;
            }
            if (elemData is ConstantInputData)
            {
                ConstantInputData  inelemData = elemData as ConstantInputData;
                StateTypeConverter stateconv  = new StateTypeConverter();
                (io as ConstantInput).State = (State)stateconv.ConvertFromString(inelemData.State.Trim());
                io.OutputCount = inelemData.Outputs.Length;
                RestoreTerminals(inelemData.Outputs, io.Outputs);
            }
            if (elemData is InputElementData)
            {
                InputElementData inelemData = elemData as InputElementData;
                io.OutputCount = inelemData.Outputs.Length;
                RestoreTerminals(inelemData.Outputs, io.Outputs);
                if (signals != null)
                {
                    foreach (Signal signal in signals)
                    {
                        if (signal.Name.Equals(inelemData.SignalName))
                        {
                            (io as SignalInput).Signal = signal;
                        }
                    }
                }
            }
            if (elemData is OutputElementData)
            {
                OutputElementData outelemData = elemData as OutputElementData;
                (io as SignalOutput).SignalName = outelemData.SignalName;
                io.InputCount = outelemData.Inputs.Length;
                RestoreTerminals(outelemData.Inputs, io.Inputs);
            }
            if (elemData is IOElementData || elemData is MacroElementData)
            {
                IOElementData ioelemData = elemData as IOElementData;
                io.InputCount  = ioelemData.Inputs.Length;
                io.OutputCount = ioelemData.Outputs.Length;
                RestoreTerminals(ioelemData.Inputs, io.Inputs);
                RestoreTerminals(ioelemData.Outputs, io.Outputs);
                io.UpdateIndex  = ioelemData.Index;
                io.UnitDelay    = ioelemData.UnitDelay;
                io.NegEdgeDelay = ioelemData.NegativeEdgeDelay;
                io.PosEdgeDelay = ioelemData.PositiveEdgeDelay;
            }
            io.Name = elemData.Name;
            elemDict.Add(io, elemData);
            return(io);
        }
        private BaseElementData ConvertIOElement(BaseElement element)
        {
            BaseElementData elemData = null;

            if (element is Macro)
            {
                Macro            macro     = (Macro)element;
                MacroElementData macroData = new MacroElementData(macro.Name, macro.TypeName, macro.FileReference);
                macroData.Inputs            = ConvertTerminalArray(macro.Inputs);
                macroData.Outputs           = ConvertTerminalArray(macro.Outputs);
                macroData.Index             = macro.UpdateIndex;
                macroData.UnitDelay         = macro.UnitDelay;
                macroData.NegativeEdgeDelay = macro.NegEdgeDelay;
                macroData.PositiveEdgeDelay = macro.PosEdgeDelay;
                elemData = macroData;
            }
            if (element is Clock)
            {
                Clock     clock     = (Clock)element;
                ClockData clockData = new ClockData(clock.Name, clock.LowDuration, clock.HighDuration);
                clockData.Outputs = ConvertTerminalArray(clock.Outputs);
                elemData          = clockData;
            }
            if (element is SignalInput)
            {
                SignalInput      sigInput = (SignalInput)element;
                InputElementData inData   = new InputElementData(sigInput.Name, sigInput.SignalName);
                inData.Outputs = ConvertTerminalArray(sigInput.Outputs);
                elemData       = inData;
            }
            else if (element is ConstantInput)
            {
                ConstantInput     conInput = (ConstantInput)element;
                ConstantInputData inData   = new ConstantInputData(conInput.Name, conInput.State.ToString());
                inData.Outputs = ConvertTerminalArray(conInput.Outputs);
                elemData       = inData;
            }
            if (element is SignalOutput)
            {
                SignalOutput      sigOutput = (SignalOutput)element;
                OutputElementData outData   = new OutputElementData(sigOutput.Name, sigOutput.SignalName);
                outData.Inputs = ConvertTerminalArray(sigOutput.Inputs);
                elemData       = outData;
            }
            if (elemData == null && element is InputOutputElement)
            {
                InputOutputElement io     = (InputOutputElement)element;
                IOElementData      ioData = new IOElementData(io.Name, element.GetType().Name);
                ioData.Inputs            = ConvertTerminalArray(io.Inputs);
                ioData.Outputs           = ConvertTerminalArray(io.Outputs);
                ioData.Index             = io.UpdateIndex;
                ioData.UnitDelay         = io.UnitDelay;
                ioData.NegativeEdgeDelay = io.NegEdgeDelay;
                ioData.PositiveEdgeDelay = io.PosEdgeDelay;
                elemData = ioData;
            }
            if (elemData == null)
            {
                return(null);
            }
            if (element.LinkedObject != null)
            {
                GraphicInputOutputElement grIO = element.LinkedObject as GraphicInputOutputElement;
                elemData.X = grIO.Location.X;
                elemData.Y = grIO.Location.Y;
            }
            return(elemData);
        }