public List<ProjectBlockInfo> readPlcBlocksList()
        {
            SymbolTable symtab = null;
            if (((S7ProgrammFolder)Parent) != null)
                symtab = (SymbolTable)((S7ProgrammFolder) Parent).SymbolTable;

            List<ProjectBlockInfo> retVal=new List<ProjectBlockInfo>();

            Connection.Connect();
            List<string> blks = Connection.PLCListBlocks(PLCBlockType.AllBlocks);

            foreach (var blk in blks)
            {
                ProjectPlcBlockInfo tmp = new ProjectPlcBlockInfo();
                tmp.ParentFolder = this;
                if (blk.Substring(0, 2) == "DB")
                {
                    tmp.BlockType = PLCBlockType.DB;
                    tmp.BlockNumber = Convert.ToInt32(blk.Substring(2));
                }
                else if (blk.Substring(0, 2) == "OB")
                {
                    tmp.BlockType = PLCBlockType.OB;
                    tmp.BlockNumber = Convert.ToInt32(blk.Substring(2));
                }
                else if (blk.Substring(0, 2) == "FC")
                {
                    tmp.BlockType = PLCBlockType.FC;
                    tmp.BlockNumber = Convert.ToInt32(blk.Substring(2));
                }
                else if (blk.Substring(0, 2) == "FB")
                {
                    tmp.BlockType = PLCBlockType.FB;
                    tmp.BlockNumber = Convert.ToInt32(blk.Substring(2));
                }
                else if (blk.Substring(0, 3) == "SFC")
                {
                    tmp.BlockType = PLCBlockType.SFC;
                    tmp.BlockNumber = Convert.ToInt32(blk.Substring(3));
                }
                else if (blk.Substring(0, 3) == "SFB")
                {
                    tmp.BlockType = PLCBlockType.SFB;
                    tmp.BlockNumber = Convert.ToInt32(blk.Substring(3));
                }
                else if (blk.Substring(0, 3) == "SDB")
                {
                    tmp.BlockType = PLCBlockType.SDB;
                    tmp.BlockNumber = Convert.ToInt32(blk.Substring(3));
                }

                /*
                if (symtab != null)
                {
                    SymbolTableEntry sym = symtab.GetEntryFromOperand(tmp.ToString());
                    if (sym != null)
                        tmp.Symbol = sym.Symbol;
                }
                */
                retVal.Add(tmp);
            }


            return retVal;
        }
        public static S5FunctionBlock GetFunctionBlock(ProjectPlcBlockInfo blkInfo, byte[] block, byte[] preHeader, byte[] commentBlock, Step5ProgrammFolder prjBlkFld)
        {
            S5FunctionBlock retVal = new S5FunctionBlock();

            retVal.BlockType = blkInfo.BlockType;
            retVal.BlockNumber = blkInfo.BlockNumber;

            if (blkInfo.BlockType == PLCBlockType.S5_PB || blkInfo.BlockType == PLCBlockType.S5_SB || blkInfo.BlockType == PLCBlockType.S5_OB)
                retVal.AWLCode = GetMC5Rows(block, 10, null, (Step5BlocksFolder) blkInfo.ParentFolder, retVal);
            else
            {
                string fbNM = System.Text.Encoding.GetEncoding("ISO-8859-1").GetString(block, 12, 8);

                retVal.Name = fbNM;

                List<S5Parameter> pars = GetParameters(block);

                retVal.Parameter = pars;

                retVal.AWLCode = GetMC5Rows(block, /*10 + spa*2*/ 10 + ((pars.Count*3) + 5)*2, pars, (Step5BlocksFolder) blkInfo.ParentFolder, retVal);
            }
            //Go throug retval and add Symbols...
            if (prjBlkFld != null)
            {
                if (prjBlkFld.SymbolTable != null)
                {
                    foreach (S5FunctionBlockRow awlRow in retVal.AWLCode)
                    {
                        string para = awlRow.Parameter.Replace(" ", "");

                        awlRow.SymbolTableEntry = prjBlkFld.SymbolTable.GetEntryFromOperand(para);
                    }
                }
            }

            retVal.Networks = new List<Network>();

            S5FunctionBlockNetwork nw = null; 

            if (retVal.AWLCode != null)
                foreach (S5FunctionBlockRow s5FunctionBlockRow in retVal.AWLCode)
                {
                    if (s5FunctionBlockRow.Command == "BLD" && s5FunctionBlockRow.Parameter == "255")
                    {
                        if (nw != null)
                            nw.AWLCode.Add(s5FunctionBlockRow);                     
                        nw = new S5FunctionBlockNetwork();
                        nw.Parent = retVal;
                        nw.AWLCode = new List<FunctionBlockRow>();
                        ((S5FunctionBlockNetwork) nw).NetworkFunctionBlockRow = s5FunctionBlockRow;
                        retVal.Networks.Add(nw);
                    }
                    else
                    {
                        nw.AWLCode.Add(s5FunctionBlockRow);
                    }

                }

            if (commentBlock != null)
            {
                int nr = 26;
                int netzwnr = 0;
                Dictionary<int, object> commandLineNumerList = new Dictionary<int, object>();
                while (nr + 3 < commentBlock.Length)
                {
                    int zeile = commentBlock[nr];

                    int len = 0x7f & commentBlock[nr + 2];
                    string cmt = System.Text.Encoding.GetEncoding("ISO-8859-1").GetString(commentBlock, nr + 3, len);

                    if (commentBlock[nr + 1] == 0x00)
                    {
                        netzwnr = zeile;
                        if (retVal.Networks.Count>netzwnr - 1 && netzwnr>0)
                        {
                            ((S5FunctionBlockNetwork) retVal.Networks[netzwnr - 1]).Name = cmt;
                            commandLineNumerList.Clear();
                            int lineNr = 0;
                            foreach (S5FunctionBlockRow akRow in retVal.Networks[netzwnr - 1].AWLCode)
                            {

                                commandLineNumerList.Add(lineNr, akRow);
                                lineNr++;

                                if (IsCall(akRow))
                                {
                                    foreach (S5Parameter extPar in akRow.ExtParameter)
                                    {
                                        commandLineNumerList.Add(lineNr, extPar);
                                        lineNr++;
                                    }
                                }
                            }
                        }
                        else
                        {
                            //Todo: Throw an error when this happens???
                            //throw new Exception("Error in Block: " + retVal.BlockName);
                        }

                    }
                    else
                    {
                        if (commandLineNumerList.ContainsKey(zeile - 1))
                        {
                            object obj = commandLineNumerList[zeile - 1];
                            if (obj is S5Parameter)
                                ((S5Parameter) obj).Comment = cmt;
                            else
                                ((S5FunctionBlockRow) obj).Comment = cmt;
                        }
                    }
                    nr += len + 3;
                }

            }

            return retVal;
        }
        public static S5DataBlock GetDB(ProjectPlcBlockInfo blkInfo, byte[] block, byte[] preHeader, byte[] commentBlock)
        {
            S5DataBlock retVal = new S5DataBlock();

            retVal.BlockType = blkInfo.BlockType;
            retVal.BlockNumber = blkInfo.BlockNumber;

            S7DataRow main = new S7DataRow("STATIC", S7DataRowType.STRUCT, retVal);
            retVal.Structure = main;

            var zeilenListe = new List<S7DataRow>();

            if (preHeader != null)
            {
                int akcnt = 0;
                //S7DataRowType akRwTp = (S7DataRowType) (preHeader[9] | 0xf00);
                int anzTypes = (((preHeader[6] * 256 + preHeader[7]) - 2)/2); //How many different Types are in the Header
                for (int n = 1; n <= anzTypes; n++)
                {
                    int rowStart = preHeader[(n - 1) * 4 + 10] * 256 + preHeader[(n - 1) * 4 + 11];
                    int rowStop = preHeader[n * 4 + 10] * 256 + preHeader[n * 4 + 11];
                    var akRwTp = (S7DataRowType)(preHeader[9 + (n - 1) * 4] | 0xf00);
                    

                    if (akRwTp == S7DataRowType.S5_C || akRwTp == S7DataRowType.S5_KC)
                    {
                        for (int j = rowStart; j < rowStop; j += 24)
                        {
                            var row = new S7DataRow(string.Empty, akRwTp, retVal);
                            row.StringSize = rowStop - j > 12 ? 24 : (rowStop - j)*2;
                            main.Add(row);
                            for (int q = 0; q < (row.StringSize/2); q++)
                            {
                                zeilenListe.Add(row);
                            }
                        }
                    }
                    else if (akRwTp == S7DataRowType.S5_KG)
                    {
                        for (int j = rowStart; j < rowStop; j += 2)
                        {
                            var row = new S7DataRow(string.Empty, akRwTp, retVal);
                            main.Add(row);
                            zeilenListe.Add(row);
                            zeilenListe.Add(row);
                        }
                    }
                    else
                    {
                        for (int j = rowStart; j < rowStop; j += 1)
                        {
                            var row = new S7DataRow(string.Empty, akRwTp, retVal);
                            main.Add(row);
                            zeilenListe.Add(row);
                        }
                    }                                                           
                }

            }

            
            try
            {
                int st = 10;

                int maxZ = (block[8] * 256 + block[9]);
                int n = 0;

                while(n < maxZ - 5)
                    //foreach (var s7DataRow in main.Children)
                {
                    S7DataRow s7DataRow;
                    if (zeilenListe.Count > n) 
                        s7DataRow = zeilenListe[n];
                    else
                    {
                        s7DataRow = new S7DataRow(string.Empty, S7DataRowType.S5_KH, retVal);
                        main.Add(s7DataRow);
                    }

                    switch (s7DataRow.DataType)
                    {
                        case S7DataRowType.S5_KF:
                            s7DataRow.Value = libnodave.getS16from(block, st);
                            break;
                        case S7DataRowType.S5_KZ:
                            s7DataRow.Value = libnodave.getBCD16from(block, st);
                            break;
                        case S7DataRowType.S5_KM:
                            s7DataRow.Value = libnodave.getU16from(block, st);
                            break;
                        case S7DataRowType.S5_KH:
                            s7DataRow.Value = libnodave.getU16from(block, st);
                            break;
                        case S7DataRowType.S5_KY:
                            s7DataRow.Value = libnodave.getU16from(block, st);
                            break;
                        case S7DataRowType.S5_KG:
                            s7DataRow.Value = libnodave.getS5Floatfrom(block, st);
                            break;
                        case S7DataRowType.S5_KC:
                        case S7DataRowType.S5_C:
                            s7DataRow.Value = System.Text.ASCIIEncoding.ASCII.GetString(block, st, s7DataRow.StringSize);
                            break;
                        case S7DataRowType.S5_KT:
                            s7DataRow.Value = libnodave.getS5Timefrom(block, st);
                            break;
                        default:
                            s7DataRow.Value = libnodave.getU16from(block, st);                        
                            break;
                    }

                    st += s7DataRow.ByteLength;
                    n += s7DataRow.ByteLength / 2;
                }
            }
            catch (Exception ex)
            { }


            try
            {
                if (commentBlock != null && main._children != null && main._children.Count > 0)
                {
                    int nr = 28;
                    int hdlen = 0x7f & commentBlock[nr];

                    retVal.Name = System.Text.Encoding.GetEncoding("ISO-8859-1").GetString(commentBlock, nr + 1, hdlen);

                    nr += hdlen + 1;
                    while (nr + 3 < commentBlock.Length)
                    {
                        int zeile = ((commentBlock[nr + 1] - 128) * 256) + commentBlock[nr];
                        int len = 0x7f & commentBlock[nr + 2];
                        string cmt = System.Text.Encoding.GetEncoding("ISO-8859-1").GetString(commentBlock, nr + 3, len);
                        //main._children[zeile].Comment = cmt;
                        zeilenListe[zeile].Comment = cmt;

                        nr += len + 3;
                    }

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("There was an error parsing the Block Comments! Maybe the Step5 project is broken? \n" + ex.Message);
            }

            return retVal;
        }