Example #1
0
        internal SelectStatement From(StagingTable stagingTable, ColumnTypes?allowedColumnTypes = null)
        {
            this.from = stagingTable;
            this.allowedColumnTypes = allowedColumnTypes ?? this.allowedColumnTypes;

            return(this);
        }
Example #2
0
        // Return a mapping table based on table name
        // @param id table identifier
        // @return Table object
        public StagingTable getTable(String id)
        {
            ITable       thisTable = _provider.getTable(id);
            StagingTable oRetval   = (StagingTable)thisTable;

            return(oRetval);
        }
Example #3
0
        public void testInputTables()
        {
            HashSet <String> errors = new HashSet <String>();

            foreach (String schemaId in _STAGING.getSchemaIds())
            {
                StagingSchema schema = _STAGING.getSchema(schemaId);

                // build a list of input tables that should be excluded
                foreach (StagingSchemaInput input in schema.getInputs())
                {
                    if (input.getTable() != null)
                    {
                        HashSet <String> inputKeys = new HashSet <String>();
                        StagingTable     table     = _STAGING.getTable(input.getTable());
                        foreach (StagingColumnDefinition def in table.getColumnDefinitions())
                        {
                            if (ColumnType.INPUT == def.getType())
                            {
                                inputKeys.Add(def.getKey());
                            }
                        }

                        // make sure the input key matches the an input column
                        if (!inputKeys.Contains(input.getKey()))
                        {
                            errors.Add("Input key " + schemaId + ":" + input.getKey() + " does not match validation table " + table.getId() + ": " + inputKeys.ToString());
                        }
                    }
                }
            }

            assertNoErrors(errors, "input values and their assocated validation tables");
        }
        // Given a table, return a Set of all the distinct input values.  This is for tables that have a single INPUT column.
        // @param tableId table identifier
        // @return A set of unique inputs
        private HashSet <String> getAllInputValues(String tableId)
        {
            HashSet <String> values = new HashSet <String>();

            // if the table is not found, return right away with an empty list
            //StagingTable table = (getTable(tableId) as StagingTable);
            StagingTable table = (StagingTable)(getTable(tableId));

            if (table == null)
            {
                return(values);
            }

            // find the input key
            HashSet <String> inputKeys = new HashSet <String>();

            foreach (StagingColumnDefinition col in table.getColumnDefinitions())
            {
                if (col.getType() == ColumnType.INPUT)
                {
                    inputKeys.Add(col.getKey());
                }
            }

            if (inputKeys.Count != 1)
            {
                throw new System.InvalidOperationException("Table '" + table.getId() + "' must have one and only one INPUT column.");
            }

            HashSet <String> .Enumerator enumInput = inputKeys.GetEnumerator();
            enumInput.MoveNext();
            String inputKey = enumInput.Current;

            foreach (StagingTableRow row in table.getTableRows())
            {
                foreach (StagingRange range in row.getColumnInput(inputKey))
                {
                    if (range.getLow() != null)
                    {
                        if (range.getLow() == range.getHigh())
                        {
                            values.Add(range.getLow());
                        }
                        else
                        {
                            int low  = Convert.ToInt32(range.getLow());
                            int high = Convert.ToInt32(range.getHigh());

                            // add all values in range
                            for (int i = low; i <= high; i++)
                            {
                                values.Add(padStart(i.ToString(), range.getLow().Length, '0'));
                            }
                        }
                    }
                }
            }

            return(values);
        }
Example #5
0
        public void testEncoding()
        {
            StagingTable table = _STAGING.getTable("serum_alb_pretx_level_58159");

            Assert.IsNotNull(table);

            // the notes of this table contain UTF-8 characters, specifically the single quote character in this phrase: "You may use a physician’s statement"

            // converting to UTF-8 should change nothing
            String OrigNotes = table.getNotes();

            byte[] utf8Bytes = Encoding.UTF8.GetBytes(OrigNotes);
            char[] utf8Chars = new char[Encoding.UTF8.GetCharCount(utf8Bytes, 0, utf8Bytes.Length)];
            Encoding.UTF8.GetChars(utf8Bytes, 0, utf8Bytes.Length, utf8Chars, 0);
            string utf8String = new string(utf8Chars);

            Assert.AreEqual(table.getNotes(), utf8String);


            // converting to other encoding should change the text
            byte[] asciiBytes = Encoding.ASCII.GetBytes(OrigNotes);
            char[] asciiChars = new char[Encoding.ASCII.GetCharCount(asciiBytes, 0, asciiBytes.Length)];
            Encoding.ASCII.GetChars(asciiBytes, 0, asciiBytes.Length, asciiChars, 0);
            string asciiString = new string(asciiChars);

            Assert.AreNotEqual(table.getNotes(), asciiString);
        }
        public void testTableRowParsing()
        {
            StagingTable table = new StagingTable();

            table.setId("test_table");
            table.setColumnDefinitions(new List <IColumnDefinition>()
            {
                new StagingColumnDefinition("key1", "Input 1", ColumnType.INPUT)
            });
            table.setRawRows(new List <List <String> >());
            table.getRawRows().Add(new List <String>()
            {
                ",1,2,3"
            });
            table.getRawRows().Add(new List <String>()
            {
                "1,2,3,"
            });

            StagingDataProvider.initTable(table);

            Assert.AreEqual(2, table.getTableRows().Count);


            //StagingTableRow
            List <ITableRow> tablerows = table.getTableRows();

            StagingTableRow row = (tablerows[0] as StagingTableRow);

            Assert.AreEqual(4, row.getInputs()["key1"].Count);

            row = (tablerows[1] as StagingTableRow);
            Assert.AreEqual(4, row.getInputs()["key1"].Count);
        }
        public override ITable getTable(String id)
        {
            StagingTable oRetval = null;

            _tables.TryGetValue(id, out oRetval);

            return(oRetval);
        }
        /**
         * Add a table
         */
        public void addTable(StagingTable table)
        {
            initTable(table);
            _tables[table.getId()] = table;

            foreach (KeyValuePair <string, StagingTable> entry in _tables)
            {
                _TableKeys.Add(entry.Key);
            }
        }
Example #9
0
        public void testInitAllTables()
        {
            foreach (String id in _STAGING.getTableIds())
            {
                StagingTable table = _STAGING.getTable(id);

                Assert.IsNotNull(table);
                Assert.IsNotNull(table.getAlgorithm());
                Assert.IsNotNull(table.getVersion());
                Assert.IsNotNull(table.getName());
            }
        }
        public void testRangeParsing()
        {
            StagingTable table = _STAGING.getTable("path_n_daj");

            Assert.IsNotNull(table);
            Assert.AreEqual("p0I-", table.getRawRows()[2][0]);

            StagingTableRow tablerow = (table.getTableRows()[2] as StagingTableRow);

            Assert.AreEqual("p0I-", tablerow.getInputs()["path_n"][0].getLow());

            tablerow = (table.getTableRows()[2] as StagingTableRow);
            Assert.AreEqual("p0I-", tablerow.getInputs()["path_n"][0].getHigh());
        }
        // Look up a schema based on site, histology and an optional discriminator.
        // @param lookup schema lookup input
        // @return a list of StagingSchemaInfo objects
        private List <StagingSchema> getSchemas(SchemaLookup lookup)
        {
            List <StagingSchema> matchedSchemas = new List <StagingSchema>(5);

            String site             = lookup.getInput(StagingData.PRIMARY_SITE_KEY);
            String histology        = lookup.getInput(StagingData.HISTOLOGY_KEY);
            bool   hasDiscriminator = lookup.hasDiscriminator();

            // site or histology must be supplied and they must be valid; I am assuming that all algorithms must have tables that validate
            // both site and histology
            if ((site != null && !isValidSite(site)) || (histology != null && !isValidHistology(histology)))
            {
                return(matchedSchemas);
            }

            // searching on a discriminator is only supported if also searching on site and histology; if ssf25 supplied without either
            // of those fields, return no results
            if (hasDiscriminator && (site == null || (site.Length == 0) || histology == null || (histology.Length == 0)))
            {
                return(matchedSchemas);
            }

            // site or histology must be supplied
            if (site != null || histology != null)
            {
                HashSet <String> lstSchemaIds = getSchemaIds();

                // loop over selection table and match using only the supplied keys
                foreach (String schemaId in lstSchemaIds)
                {
                    StagingSchema schema = (StagingSchema)(getDefinition(schemaId));

                    if (schema.getSchemaSelectionTable() != null)
                    {
                        StagingTable table = (StagingTable)(getTable(schema.getSchemaSelectionTable()));
                        if (table != null && DecisionEngineFuncs.matchTable(table, lookup.getInputs(), lookup.getKeys()) != null)
                        {
                            matchedSchemas.Add(schema);
                        }
                    }
                }
            }

            return(matchedSchemas);
        }
        public void testNumericRangeTableMatch()
        {
            InMemoryDataProvider provider = new InMemoryDataProvider("test", "1.0");

            StagingTable table = new StagingTable();

            table.setId("psa");
            StagingColumnDefinition def1 = new StagingColumnDefinition();

            def1.setKey("psa");
            def1.setName("PSA Value");
            def1.setType(ColumnType.INPUT);
            StagingColumnDefinition def2 = new StagingColumnDefinition();

            def2.setKey("description");
            def2.setName("PSA Description");
            def2.setType(ColumnType.DESCRIPTION);
            table.setColumnDefinitions(new List <IColumnDefinition>()
            {
                def1, def2
            });
            table.setRawRows(new List <List <String> >());
            table.getRawRows().Add(new List <String>()
            {
                "0.1", "0.1 or less nanograms/milliliter (ng/ml)"
            });
            table.getRawRows().Add(new List <String>()
            {
                "0.2-999.9", "0.2 – 999.9 ng/ml"
            });
            provider.addTable(table);

            TNMStagingCSharp.Src.Staging.Staging staging = TNMStagingCSharp.Src.Staging.Staging.getInstance(provider);

            Assert.AreEqual(0, staging.findMatchingTableRow("psa", "psa", "0.1"));
            Assert.AreEqual(1, staging.findMatchingTableRow("psa", "psa", "0.2"));
            Assert.AreEqual(1, staging.findMatchingTableRow("psa", "psa", "500"));
            Assert.AreEqual(1, staging.findMatchingTableRow("psa", "psa", "500.99"));
            Assert.AreEqual(1, staging.findMatchingTableRow("psa", "psa", "500.0001"));
            Assert.AreEqual(1, staging.findMatchingTableRow("psa", "psa", "999.9"));
            Assert.AreEqual(-1, staging.findMatchingTableRow("psa", "psa", "1000"));
            Assert.AreEqual(-1, staging.findMatchingTableRow("psa", "psa", "-1"));
            Assert.AreEqual(-1, staging.findMatchingTableRow("psa", "psa", "0.01"));
        }
Example #13
0
        // * Return the input length from a specified table
        // * @param tableId table indentifier
        // * @param key input key
        // * @return null if no length couild be determined, or the length
        protected int getInputLength(String tableId, String key)
        {
            StagingTable table  = _STAGING.getTable(tableId);
            int          length = -1;

            // loop over each row
            foreach (StagingTableRow row in table.getTableRows())
            {
                List <Range> ranges = row.getInputs()[key];

                foreach (StagingRange range in ranges)
                {
                    String low  = range.getLow();
                    String high = range.getHigh();

                    if (range.matchesAll() || low.Length == 0)
                    {
                        continue;
                    }

                    if (low.StartsWith("{{") && low.Contains(TNMStagingCSharp.Src.Staging.Staging.CTX_YEAR_CURRENT))
                    {
                        low = DateTime.Now.Year.ToString();
                    }
                    if (high.StartsWith("{{") && high.Contains(TNMStagingCSharp.Src.Staging.Staging.CTX_YEAR_CURRENT))
                    {
                        high = DateTime.Now.Year.ToString();
                    }

                    if (length >= 0 && (low.Length != length || high.Length != length))
                    {
                        throw new System.InvalidOperationException("Inconsistent lengths in table " + tableId + " for key " + key);
                    }

                    length = low.Length;
                }
            }

            return(length);
        }
Example #14
0
        public new void UpdateTables(Dictionary <string, Column> suggestedColumnDict)
        {
            if (suggestedColumnDict == null)
            {
                throw new ArgumentNullException(nameof(suggestedColumnDict));
            }

            if (LoadTable == null)
            {
                LoadTable = new LoadTable();
            }

            if (StagingTable == null)
            {
                StagingTable = new StagingTable();
            }

            // Update existing columns
            foreach (Column stagingColumn in StagingTable.Columns !)
            {
                if (!string.IsNullOrEmpty(stagingColumn.Name) && suggestedColumnDict.ContainsKey(stagingColumn.Name !))
                {
                    StagingColumn suggestedColumn = (StagingColumn)suggestedColumnDict[stagingColumn.Name !];
Example #15
0
        // Looks at all tables involved in all the mappings in the definition and returns a list of input keys that could be used.  It will also deal with mapped
        // inputs.  The inputs from each mapping will only be included if it passes the inclusion/exclusion criteria based on the context.  Note that if an input
        // to a table was not a supplied input (i.e. it was created as an output of a previous table) it will not be included in the list of inputs.  The inputs will
        // also include any used in schema selection.  All inputs returned from this method should be in the schema input list otherwise there is a problem with the
        // schema.
        // @param schema a StagingSchema
        // @param context a context of values used to to check mapping inclusion/exclusion
        // @return a Set of unique input keys
        public HashSet <String> getInputs(StagingSchema schema, Dictionary <String, String> context)
        {
            HashSet <String> inputs = new HashSet <String>();

            // add schema selection fields
            if (schema.getSchemaSelectionTable() != null)
            {
                StagingTable table = getTable(schema.getSchemaSelectionTable());
                if (table != null)
                {
                    foreach (StagingColumnDefinition def in table.getColumnDefinitions())
                    {
                        if (ColumnType.INPUT == def.getType())
                        {
                            inputs.Add(def.getKey());
                        }
                    }
                }
            }

            // process all mappings
            if (schema.getMappings() != null)
            {
                HashSet <String> excludedInputs = new HashSet <String>();
                HashSet <String> thisInput      = null;
                foreach (StagingMapping mapping in schema.getMappings())
                {
                    thisInput = getInputs(mapping, context, excludedInputs);
                    inputs.UnionWith(thisInput);
                }
            }

            // always remove all context variables since they are never needed to be supplied
            inputs.ExceptWith(CONTEXT_KEYS);

            return(inputs);
        }
        public void testBlankInputs()
        {
            InMemoryDataProvider provider = new InMemoryDataProvider("test", "1.0");

            StagingTable table = new StagingTable();

            table.setId("table_input1");
            StagingColumnDefinition def1 = new StagingColumnDefinition();

            def1.setKey("input1");
            def1.setName("Input 1");
            def1.setType(ColumnType.INPUT);
            StagingColumnDefinition def2 = new StagingColumnDefinition();

            def2.setKey("result1");
            def2.setName("Result1");
            def2.setType(ColumnType.DESCRIPTION);
            table.setColumnDefinitions(new List <IColumnDefinition>()
            {
                def1, def2
            });
            table.setRawRows(new List <List <String> >());
            table.getRawRows().Add(new List <String>()
            {
                "1", "ONE"
            });
            table.getRawRows().Add(new List <String>()
            {
                "2", "TWO"
            });
            provider.addTable(table);

            table = new StagingTable();
            table.setId("table_input2");
            def1 = new StagingColumnDefinition();
            def1.setKey("input2");
            def1.setName("Input 2");
            def1.setType(ColumnType.INPUT);
            def2 = new StagingColumnDefinition();
            def2.setKey("result2");
            def2.setName("Result2");
            def2.setType(ColumnType.DESCRIPTION);
            table.setColumnDefinitions(new List <IColumnDefinition>()
            {
                def1, def2
            });
            table.setRawRows(new List <List <String> >());
            table.getRawRows().Add(new List <String>()
            {
                "", "Blank"
            });
            table.getRawRows().Add(new List <String>()
            {
                "A", "Letter A"
            });
            table.getRawRows().Add(new List <String>()
            {
                "B", "Letter B"
            });
            provider.addTable(table);

            table = new StagingTable();
            table.setId("table_selection");
            def1 = new StagingColumnDefinition();
            def1.setKey("input1");
            def1.setName("Input 1");
            def1.setType(ColumnType.INPUT);
            table.setColumnDefinitions(new List <IColumnDefinition>()
            {
                def1
            });
            table.setRawRows(new List <List <String> >());
            table.getRawRows().Add(new List <String>()
            {
                "*"
            });
            provider.addTable(table);

            table = new StagingTable();
            table.setId("primary_site");
            def1 = new StagingColumnDefinition();
            def1.setKey("site");
            def1.setName("Site");
            def1.setType(ColumnType.INPUT);
            table.setColumnDefinitions(new List <IColumnDefinition>()
            {
                def1
            });
            table.setRawRows(new List <List <String> >());
            table.getRawRows().Add(new List <String>()
            {
                "C509"
            });
            provider.addTable(table);

            table = new StagingTable();
            table.setId("histology");
            def1 = new StagingColumnDefinition();
            def1.setKey("hist");
            def1.setName("Histology");
            def1.setType(ColumnType.INPUT);
            table.setColumnDefinitions(new List <IColumnDefinition>()
            {
                def1
            });
            table.setRawRows(new List <List <String> >());
            table.getRawRows().Add(new List <String>()
            {
                "8000"
            });
            provider.addTable(table);

            table = new StagingTable();
            table.setId("table_year_dx");
            def1 = new StagingColumnDefinition();
            def1.setKey("year_dx");
            def1.setName("Year DX");
            def1.setType(ColumnType.INPUT);
            table.setColumnDefinitions(new List <IColumnDefinition>()
            {
                def1
            });
            table.setRawRows(new List <List <String> >());
            table.getRawRows().Add(new List <String>()
            {
                "1900-2100"
            });
            provider.addTable(table);

            StagingSchema schema = new StagingSchema();

            schema.setId("schema_test");
            schema.setSchemaSelectionTable("table_selection");
            List <StagingSchemaInput> inputs = new List <StagingSchemaInput>();

            inputs.Add(new StagingSchemaInput("site", "Primary Site", "primary_site"));
            inputs.Add(new StagingSchemaInput("hist", "Hist", "histology"));
            inputs.Add(new StagingSchemaInput("year_dx", "Year DX", "table_year_dx"));
            inputs.Add(new StagingSchemaInput("input1", "Input 1", "table_input1"));
            inputs.Add(new StagingSchemaInput("input2", "Input 2", "table_input2"));
            schema.setInputs(inputs);

            provider.addSchema(schema);

            TNMStagingCSharp.Src.Staging.Staging staging = TNMStagingCSharp.Src.Staging.Staging.getInstance(provider);


            Assert.AreEqual("schema_test", staging.getSchema("schema_test").getId());

            // check case where required input field not supplied (i.e. no default); since there are is no workflow defined, this should
            // not cause an error

            StagingData data = new StagingData("C509", "8000");

            data.setInput("year_dx", "2018");
            data.setInput("input1", "1");

            staging.stage(data);
            Assert.AreEqual(StagingData.Result.STAGED, data.getResult());

            // pass in blank for "input2"
            data = new StagingData("C509", "8000");
            data.setInput("year_dx", "2018");
            data.setInput("input1", "1");
            data.setInput("input2", "");

            staging.stage(data);
            Assert.AreEqual(StagingData.Result.STAGED, data.getResult());

            // pass in null for "input2"

            data = new StagingData("C509", "8000");
            data.setInput("year_dx", "2018");
            data.setInput("input1", "1");
            data.setInput("input2", null);

            staging.stage(data);
            Assert.AreEqual(StagingData.Result.STAGED, data.getResult());
        }
Example #17
0
        // Initialize data provider
        private void init(Stream inStream)
        {
            HashSet <String> algorithms = new HashSet <String>();
            HashSet <String> versions   = new HashSet <String>();


            using (ZipArchive archive = new ZipArchive(inStream, ZipArchiveMode.Read))
            {
                foreach (ZipArchiveEntry entry in archive.Entries)
                {
                    if ((entry.Name.Length == 0) || (!entry.Name.EndsWith(".json")))
                    {
                        continue;
                    }

                    if (entry.FullName.StartsWith("tables"))
                    {
                        String       s     = extractEntry(entry);
                        StagingTable table = new StagingTable();
                        table = Newtonsoft.Json.JsonConvert.DeserializeObject <StagingTable>(s);

                        if (DebugSettings.DEBUG_LOADED_TABLES)
                        {
                            Debug.WriteLine("Table: ");
                            Debug.WriteLine(table.GetDebugString("  "));
                        }

                        initTable(table);

                        algorithms.Add(table.getAlgorithm());
                        versions.Add(table.getVersion());

                        _tables[table.getId()] = table;
                    }
                    else if (entry.FullName.StartsWith("schemas"))
                    {
                        String        s      = extractEntry(entry);
                        StagingSchema schema = new StagingSchema();
                        schema = Newtonsoft.Json.JsonConvert.DeserializeObject <StagingSchema>(s);

                        if (DebugSettings.DEBUG_LOADED_SCHEMAS)
                        {
                            Debug.WriteLine("Schema: ");
                            Debug.WriteLine(schema.GetDebugString("  "));
                        }

                        initSchema(schema);

                        algorithms.Add(schema.getAlgorithm());
                        versions.Add(schema.getVersion());

                        _schemas[schema.getId()] = schema;
                    }
                }
            }

            // verify that all the algorithm names and versions are consistent
            if (algorithms.Count != 1)
            {
                throw new System.InvalidOperationException("Error initializing provider; only a single algorithm should be included in file");
            }
            if (versions.Count != 1)
            {
                throw new System.InvalidOperationException("Error initializing provider; only a single version should be included in file");
            }

            HashSet <String> .Enumerator enumAlg = algorithms.GetEnumerator();
            HashSet <String> .Enumerator enumVer = versions.GetEnumerator();
            enumAlg.MoveNext();
            enumVer.MoveNext();
            _algorithm = enumAlg.Current;
            _version   = enumVer.Current;

            GenerateSchemaIds();
            GenerateTableIds();

            // finally, initialize any caches now that everything else has been set up
            invalidateCache();
        }
        // Constructor loads all schemas and sets up table cache
        // @param algorithm algorithm
        // @param version version
        protected StagingFileDataProvider(String algorithm, String version) : base()
        {
            _algorithm = algorithm;
            _version   = version;

            String basedir = System.IO.Directory.GetCurrentDirectory() + "\\";

            if (!Directory.Exists(basedir + "Algorithms\\"))
            {
                basedir = System.IO.Directory.GetCurrentDirectory() + "\\..\\..\\..\\";
                if (System.IO.Directory.GetCurrentDirectory().IndexOf("x64") >= 0)
                {
                    basedir += "\\..\\";
                }
                basedir += "Resources\\";
            }


            String directory = "";

            // loop over all tables and load them into Map
            try
            {
                directory = basedir + "Algorithms\\" + algorithm.ToLower() + "\\" + version + "\\tables";
                foreach (String file in readLines(directory + "\\ids.txt"))
                {
                    if (file.Length != 0)
                    {
                        TextReader   reader = getStagingInputStream(directory + "\\" + file + ".json");
                        StagingTable table  = new StagingTable();

                        using (reader)
                        {
                            Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
                            table = (StagingTable)serializer.Deserialize(reader, typeof(StagingTable));
                        }


                        initTable(table);
                        _tables[table.getId()] = table;
                    }
                }
            }
            catch (IOException e)
            {
                throw new System.InvalidOperationException("IOException reading tables: " + e.Message);
            }


            // loop over all schemas and load them into Map
            try
            {
                directory = basedir + "Algorithms\\" + algorithm.ToLower() + "\\" + version + "\\schemas";

                foreach (String file in readLines(directory + "\\ids.txt"))
                {
                    if (file.Length != 0)
                    {
                        TextReader    reader = getStagingInputStream(directory + "\\" + file + ".json");
                        StagingSchema schema = new StagingSchema();

                        using (reader)
                        {
                            Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
                            schema = (StagingSchema)serializer.Deserialize(reader, typeof(StagingSchema));
                        }

                        initSchema(schema);
                        _schemas[schema.getId()] = schema;
                    }
                }
            }
            catch (IOException e)
            {
                throw new System.InvalidOperationException("IOException reading schemas: " + e.Message);
            }

            GenerateSchemaIds();
            GenerateTableIds();

            // finally, initialize any caches now that everything else has been set up
            invalidateCache();
        }
Example #19
0
        internal SelectStatement Into(StagingTable stagingTable)
        {
            into = stagingTable;

            return(this);
        }
Example #20
0
        public dlgTable(Staging pStaging, String sSchemaName, String sTableId)
        {
            InitializeComponent();

            mStaging     = pStaging;
            msSchemaName = sSchemaName;
            msTableId    = sTableId;

            lblSchemaName.Text  = msSchemaName;
            lblTableId.Text     = msTableId;
            lblTableName.Text   = "";
            lblTitle.Text       = "";
            lblSubtitle.Text    = "";
            lblDescription.Text = "";
            //webBrTableNotes.DocumentText = "";

            StagingTable thisTable = mStaging.getTable(msTableId);

            if (thisTable != null)
            {
                lblTableName.Text   = thisTable.getName();
                lblTitle.Text       = thisTable.getTitle();
                lblSubtitle.Text    = thisTable.getSubtitle();
                lblDescription.Text = thisTable.getDescription();

                String sNotes = thisTable.getNotes();
                if (sNotes == null)
                {
                    sNotes = "";
                }

                CommonMark.CommonMarkSettings settings = CommonMark.CommonMarkSettings.Default.Clone();
                settings.RenderSoftLineBreaksAsLineBreaks = true;
                String result = CommonMark.CommonMarkConverter.Convert(sNotes, settings);
                result = result.Replace("<p>", "<p style=\"font-family=Microsoft Sans Serif;font-size:11px\">");
                webBrTableNotes.DocumentText = result;

                // Set the rows to auto size to view the contents of larger text cells
                dataGridViewTable.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;

                // Obtain the number of columns and column labels for the table
                String     ColumnName  = "";
                String     ColumnLabel = "";
                ColumnType cType       = 0;
                int        iInputCol   = 0;

                List <IColumnDefinition> cols       = thisTable.getColumnDefinitions();
                StagingColumnDefinition  thisColDef = null;
                int iNumColumns = 0;
                int iNumRows    = 0;
                if (thisTable.getRawRows() != null)
                {
                    iNumRows = thisTable.getRawRows().Count;
                }
                if (cols != null)
                {
                    iNumColumns = cols.Count;
                    //int iNumRows = TNMStage_get_table_num_rows(sAlgorithmName.c_str(), sAlgorithmVersion.c_str(), strptrTableId);
                    for (int iColIndex = 0; iColIndex < cols.Count; iColIndex++)
                    {
                        thisColDef = (StagingColumnDefinition)cols[iColIndex];
                        // Add a new column to the table data view
                        ColumnName  = "ColumnName" + iColIndex + thisColDef.getName();
                        ColumnLabel = thisColDef.getName();
                        dataGridViewTable.Columns.Add(ColumnName, ColumnLabel);

                        // Get the column type.  If the type is "INPUT" OR "DESCRIPTION", then display the column.  Otherwise skip it.
                        cType = thisColDef.getType();
                        if ((cType == ColumnType.INPUT) && (iInputCol == -1))
                        {
                            iInputCol = iColIndex;
                        }
                    }
                }

                // Set widths of columns and their text wrap mode
                int iViewableWidth = dataGridViewTable.Width;
                int iWidthDivisor  = 0;
                if (iInputCol >= 0)
                {
                    iViewableWidth = dataGridViewTable.Width - 120; // remove size of input column
                }
                if (iNumColumns > 1)
                {
                    iWidthDivisor = (int)((double)iViewableWidth / (double)(iNumColumns - 1));
                }
                else
                {
                    iWidthDivisor = 300;
                }

                for (int i = 0; i < dataGridViewTable.Columns.Count; i++)
                {
                    if (i == iInputCol)
                    {
                        if (dataGridViewTable.Columns.Count == 1)
                        {
                            dataGridViewTable.Columns[i].Width = iWidthDivisor;
                        }
                        else
                        {
                            dataGridViewTable.Columns[i].Width = 100;
                        }
                    }
                    else
                    {
                        dataGridViewTable.Columns[i].Width = iWidthDivisor;
                    }
                    dataGridViewTable.Columns[i].DefaultCellStyle.WrapMode = DataGridViewTriState.True;
                    dataGridViewTable.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
                }

                // Now loop through the table rows and add each cell to the table
                List <String> thisRow   = null;
                String        CellValue = "";
                for (int iRowIndex = 0; iRowIndex < iNumRows; iRowIndex++)
                {
                    dataGridViewTable.RowCount++;
                    dataGridViewTable.Rows[iRowIndex].Height = 40;

                    thisRow = null;
                    if (thisTable.getRawRows() != null)
                    {
                        thisRow = thisTable.getRawRows()[iRowIndex];
                    }


                    for (int iColIndex = 0; iColIndex < iNumColumns; iColIndex++)
                    {
                        thisColDef = (StagingColumnDefinition)cols[iColIndex];
                        // Get the column type.  If the type is "INPUT" OR "DESCRIPTION", then display the column.  Otherwise skip it.
                        cType = thisColDef.getType();

                        CellValue = "";
                        if (thisRow.Count > iColIndex)
                        {
                            CellValue = thisRow[iColIndex];
                        }
                        if ((cType == ColumnType.INPUT) || (cType == ColumnType.DESCRIPTION))
                        {
                            // Nothing to do here - just display the string obtained from the DLL
                            dataGridViewTable[iColIndex, iRowIndex].Value = CellValue;

                            if (cType == ColumnType.INPUT)
                            {
                                dataGridViewTable.Columns[iColIndex].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
                            }
                            else
                            {
                                dataGridViewTable.Columns[iColIndex].DefaultCellStyle.Alignment = DataGridViewContentAlignment.TopLeft;
                            }
                        }
                        else if (cType == ColumnType.ENDPOINT)   // has to be TNM_COLUMN_ENDPOINT
                        {
                            // Endpoints need a small text adjustment in order to make the viewing a little nicer
                            // You need to remove the "VALUE:" string at the beginning of the string
                            if (CellValue.StartsWith("VALUE:"))
                            {
                                CellValue = CellValue.Replace("VALUE:", "");
                            }
                            dataGridViewTable[iColIndex, iRowIndex].Value = CellValue;

                            dataGridViewTable.Columns[iColIndex].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
                        }
                    }
                }
            }
        }
        public void testExternalLoad()
        {
            Assert.AreEqual("testing", _STAGING.getAlgorithm());
            Assert.AreEqual("99.99", _STAGING.getVersion());
            Assert.AreEqual(1, _STAGING.getSchemaIds().Count);
            Assert.AreEqual(62, _STAGING.getTableIds().Count);

            StagingSchema schema = _STAGING.getSchema("urethra");

            Assert.IsNotNull(schema);
            Assert.AreEqual("testing", schema.getAlgorithm());
            Assert.AreEqual("99.99", schema.getVersion());

            StagingTable table = _STAGING.getTable("ajcc_descriptor_codes");

            Assert.IsNotNull(table);
            Assert.AreEqual("testing", table.getAlgorithm());
            Assert.AreEqual("99.99", table.getVersion());
            Assert.AreEqual(6, table.getTableRows().Count);

            HashSet <String> involved = _STAGING.getInvolvedTables("urethra");

            Assert.AreEqual(62, involved.Count);
            Assert.IsTrue(involved.Contains("mets_eval_ipa"));

            StagingData data = new StagingData();

            data.setInput("site", "C680");
            data.setInput("hist", "8000");
            data.setInput("behavior", "3");
            data.setInput("grade", "9");
            data.setInput("year_dx", "2013");
            data.setInput("cs_input_version_original", "020550");
            data.setInput("extension", "100");
            data.setInput("extension_eval", "9");
            data.setInput("nodes", "100");
            data.setInput("nodes_eval", "9");
            data.setInput("mets", "10");
            data.setInput("mets_eval", "9");

            // perform the staging
            _STAGING.stage(data);

            Assert.AreEqual(StagingData.Result.STAGED, data.getResult());
            Assert.AreEqual("urethra", data.getSchemaId());
            Assert.AreEqual(0, data.getErrors().Count);
            Assert.AreEqual(37, data.getPath().Count);

            // check output
            Assert.AreEqual("129", data.getOutput("schema_number"));
            Assert.AreEqual("020550", data.getOutput("csver_derived"));

            // AJCC 6
            Assert.AreEqual("70", data.getOutput("stor_ajcc6_stage"));

            // AJCC 7
            Assert.AreEqual("700", data.getOutput("stor_ajcc7_stage"));

            // Summary Stage
            Assert.AreEqual("7", data.getOutput("stor_ss77"));
            Assert.AreEqual("7", data.getOutput("stor_ss2000"));
        }
        public void testGetInputsWithContext()
        {
            InMemoryDataProvider provider = new InMemoryDataProvider("test", "1.0");

            StagingTable table = new StagingTable();

            table.setId("table_input1");
            StagingColumnDefinition def1 = new StagingColumnDefinition();

            def1.setKey("input1");
            def1.setName("Input 1");
            def1.setType(ColumnType.INPUT);
            table.setColumnDefinitions(new List <IColumnDefinition>()
            {
                def1
            });
            table.setRawRows(new List <List <String> >());
            table.getRawRows().Add(new List <String>()
            {
                "1"
            });
            table.getRawRows().Add(new List <String>()
            {
                "2"
            });
            provider.addTable(table);

            table = new StagingTable();
            table.setId("table_input2");
            def1 = new StagingColumnDefinition();
            def1.setKey("input1");
            def1.setName("Input 2");
            def1.setType(ColumnType.INPUT);
            table.setColumnDefinitions(new List <IColumnDefinition>()
            {
                def1
            });
            table.setRawRows(new List <List <String> >());
            table.getRawRows().Add(new List <String>()
            {
                ""
            });
            table.getRawRows().Add(new List <String>()
            {
                "A"
            });
            table.getRawRows().Add(new List <String>()
            {
                "B"
            });
            provider.addTable(table);

            table = new StagingTable();
            table.setId("table_selection");
            def1 = new StagingColumnDefinition();
            def1.setKey("input1");
            def1.setName("Input 1");
            def1.setType(ColumnType.INPUT);
            table.setColumnDefinitions(new List <IColumnDefinition>()
            {
                def1
            });
            table.setRawRows(new List <List <String> >());
            table.getRawRows().Add(new List <String>()
            {
                "*"
            });
            provider.addTable(table);

            table = new StagingTable();
            table.setId("table_mapping");

            def1 = new StagingColumnDefinition();
            def1.setKey("input1");
            def1.setName("Input 1");
            def1.setType(ColumnType.INPUT);
            StagingColumnDefinition def2 = new StagingColumnDefinition();

            def2.setKey("input2");
            def2.setName("Input 2");
            def2.setType(ColumnType.INPUT);
            StagingColumnDefinition def3 = new StagingColumnDefinition();

            def3.setKey("mapped_field");
            def3.setName("Temp value");
            def3.setType(ColumnType.INPUT);
            StagingColumnDefinition def4 = new StagingColumnDefinition();

            def4.setKey("final_output");
            def4.setName("Output");
            def4.setType(ColumnType.ENDPOINT);
            table.setColumnDefinitions(new List <IColumnDefinition>()
            {
                def1, def2, def3, def4
            });
            table.setRawRows(new List <List <String> >());
            table.getRawRows().Add(new List <String>()
            {
                "*", "*", "*", "VALUE:ABC"
            });
            provider.addTable(table);

            StagingSchema schema = new StagingSchema();

            schema.setId("schema_test");
            schema.setSchemaSelectionTable("table_selection");
            List <StagingSchemaInput> inputs = new List <StagingSchemaInput>();

            inputs.Add(new StagingSchemaInput("input1", "Input 1", "table_input1"));
            inputs.Add(new StagingSchemaInput("input2", "Input 2", "table_input2"));
            schema.setInputs(inputs);
            List <StagingSchemaOutput> outputs = new List <StagingSchemaOutput>();

            outputs.Add(new StagingSchemaOutput("final_output", "Final Output"));
            schema.setOutputs(outputs);

            StagingMapping mapping = new StagingMapping();

            mapping.setId("m1");
            List <IKeyValue> mapInitialContext = new List <IKeyValue>();

            mapInitialContext.Add(new StagingKeyValue("tmp_field", null));
            mapping.setInitialContext(mapInitialContext);
            StagingTablePath path = new StagingTablePath();

            path.setId("table_mapping");
            HashSet <IKeyMapping> pathInputMap = new HashSet <IKeyMapping>();

            pathInputMap.Add(new StagingKeyMapping("tmp_field", "mapped_field"));
            path.setInputMapping(pathInputMap);
            HashSet <String> pathInputs = new HashSet <String>();

            pathInputs.Add("input1");
            pathInputs.Add("input2");
            pathInputs.Add("tmp_field");
            path.setInputs(pathInputs);
            HashSet <String> pathOutputs = new HashSet <String>();

            pathOutputs.Add("final_output");
            path.setOutputs(pathOutputs);
            List <ITablePath> mapTablePaths = new List <ITablePath>();

            mapTablePaths.Add(path);
            mapping.setTablePaths(mapTablePaths);
            List <IMapping> schemaMappings = new List <IMapping>();

            schemaMappings.Add(mapping);
            schema.setMappings(schemaMappings);

            provider.addSchema(schema);

            TNMStagingCSharp.Src.Staging.Staging staging = TNMStagingCSharp.Src.Staging.Staging.getInstance(provider);

            HashSet <String> testSet1 = staging.getInputs(staging.getSchema("schema_test"));

            HashSet <String> testSet2 = new HashSet <String>();

            testSet2.Add("input1");
            testSet2.Add("input2");

            // should only return the "real" inputs and not the temp field set in initial context
            Assert.IsTrue(testSet1.SetEquals(testSet2));
        }
        public void testInvalidContext()
        {
            InMemoryDataProvider provider = new InMemoryDataProvider("test", "1.0");

            StagingTable table = new StagingTable();

            table.setId("table_input1");
            StagingColumnDefinition def1 = new StagingColumnDefinition();

            def1.setKey("input1");
            def1.setName("Input 1");
            def1.setType(ColumnType.INPUT);
            table.setColumnDefinitions(new List <IColumnDefinition>()
            {
                def1
            });
            table.setRawRows(new List <List <String> >());
            table.getRawRows().Add(new List <String>()
            {
                "1"
            });
            table.getRawRows().Add(new List <String>()
            {
                "2"
            });
            provider.addTable(table);

            table = new StagingTable();
            table.setId("table_selection");
            def1 = new StagingColumnDefinition();
            def1.setKey("input1");
            def1.setName("Input 1");
            def1.setType(ColumnType.INPUT);
            table.setColumnDefinitions(new List <IColumnDefinition>()
            {
                def1
            });
            table.setRawRows(new List <List <String> >());
            table.getRawRows().Add(new List <String>()
            {
                "*"
            });
            provider.addTable(table);

            table = new StagingTable();
            table.setId("table_mapping");
            def1 = new StagingColumnDefinition();
            def1.setKey("input1");
            def1.setName("Input 1");
            def1.setType(ColumnType.INPUT);
            StagingColumnDefinition def2 = new StagingColumnDefinition();

            def2.setKey("final_output");
            def2.setName("Output");
            def2.setType(ColumnType.ENDPOINT);
            table.setColumnDefinitions(new List <IColumnDefinition>()
            {
                def1, def2
            });
            table.setRawRows(new List <List <String> >());
            table.getRawRows().Add(new List <String>()
            {
                "*", "VALUE:ABC"
            });
            provider.addTable(table);

            StagingSchema schema = new StagingSchema();

            schema.setId("schema_test");
            schema.setSchemaSelectionTable("table_selection");
            List <StagingSchemaInput> inputs = new List <StagingSchemaInput>();

            inputs.Add(new StagingSchemaInput("input1", "Input 1", "table_input1"));
            schema.setInputs(inputs);
            List <StagingSchemaOutput> outputs = new List <StagingSchemaOutput>();

            outputs.Add(new StagingSchemaOutput("final_output", "Final Output"));
            schema.setOutputs(outputs);

            StagingMapping mapping = new StagingMapping();

            mapping.setId("m1");
            List <IKeyValue> mapInitialContext = new List <IKeyValue>();

            mapInitialContext.Add(new StagingKeyValue("input1", "XXX"));
            mapping.setInitialContext(mapInitialContext);
            StagingTablePath path = new StagingTablePath();

            path.setId("table_mapping");
            HashSet <String> pathInputs = new HashSet <String>();

            pathInputs.Add("input1");
            path.setInputs(pathInputs);
            HashSet <String> pathOutputs = new HashSet <String>();

            pathOutputs.Add("final_output");
            path.setOutputs(pathOutputs);

            List <ITablePath> mapTablePaths = new List <ITablePath>();

            mapTablePaths.Add(path);
            mapping.setTablePaths(mapTablePaths);
            List <IMapping> schemaMappings = new List <IMapping>();

            schemaMappings.Add(mapping);
            schema.setMappings(schemaMappings);

            try
            {
                provider.addSchema(schema);
                Assert.Fail("Add Schema should have thrown an exception.");
            } catch (System.InvalidOperationException e)
            {
                Assert.IsTrue(e.Message.Contains("not allowed since it is also defined as an input"));
            }
        }
        public void testExtraInput()
        {
            StagingTable table = new StagingTable();

            table.setId("test_table");
            StagingColumnDefinition def1 = new StagingColumnDefinition();

            def1.setKey("input1");
            def1.setName("Input 1");
            def1.setType(ColumnType.INPUT);
            StagingColumnDefinition def2 = new StagingColumnDefinition();

            def2.setKey("result1");
            def2.setName("Result1");
            def2.setType(ColumnType.ENDPOINT);
            table.setColumnDefinitions(new List <IColumnDefinition>()
            {
                def1, def2
            });
            table.setRawRows(new List <List <String> >());
            table.getRawRows().Add(new List <String>()
            {
                "1", "MATCH"
            });
            table.getRawRows().Add(new List <String>()
            {
                "2", "VALUE:{{extra1}}"
            });
            table.getRawRows().Add(new List <String>()
            {
                "{{extra2}}", "MATCH"
            });
            table.getRawRows().Add(new List <String>()
            {
                "{{ctx_year_current}}", "MATCH"
            });
            table.getRawRows().Add(new List <String>()
            {
                "5", "VALUE:{{ctx_year_current}}"
            });
            table.getRawRows().Add(new List <String>()
            {
                "6", "MATCH:{{match_extra}}"
            });
            table.getRawRows().Add(new List <String>()
            {
                "7", "ERROR:{{error_extra}}"
            });

            StagingDataProvider.initTable(table);

            HashSet <String> hash1 = new HashSet <String>()
            {
                "extra1", "extra2"
            };
            HashSet <String> hash2 = table.getExtraInput();

            // since context variables are not user-supplied, they should not be included in the extra input
            Assert.IsTrue(hash1.SetEquals(hash2));

            table.setRawRows(new List <List <String> >());
            table.getRawRows().Add(new List <String>()
            {
                "{{ctx_year_current}}", "MATCH"
            });

            StagingDataProvider.initTable(table);

            Assert.IsNull(table.getExtraInput());
        }
        private void Setup()
        {
            int        iNumColumnsUsed       = 0;
            List <int> lstDescriptionColumns = new List <int>();
            String     sColumnName           = "";
            String     sColumnLabel          = "";

            StagingTable thisTable = mStaging.getTable(msTableId);

            //String sVariableTitle = thisTable.getTitle();
            //String sVariableSubtitle = thisTable.getSubtitle();

            Text = msInputVar;

            // Convert the notes, which are in MarkDown, to HTML
            String sNotes = thisTable.getNotes();

            if (sNotes == null)
            {
                sNotes = "";
            }
            CommonMark.CommonMarkSettings settings = CommonMark.CommonMarkSettings.Default.Clone();
            settings.RenderSoftLineBreaksAsLineBreaks = true;
            String result = CommonMark.CommonMarkConverter.Convert(sNotes, settings);

            result = result.Replace("<p>", "<p style=\"font-family=Microsoft Sans Serif;font-size:11px\">");
            webBrPickerNotes.DocumentText = result;


            // Set the rows to auto size to view the contents of larger text cells
            dataGridViewPicker.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;

            // Obtain the number of columns and rows for the table
            List <IColumnDefinition> lstColDefs = thisTable.getColumnDefinitions();
            StagingColumnDefinition  thisColDef = null;
            int        iNumColumns = 0;
            int        iNumRows    = 0;
            ColumnType cType       = 0;

            if (thisTable.getRawRows() != null)
            {
                iNumRows = thisTable.getRawRows().Count;
            }
            if (lstColDefs != null)
            {
                iNumColumns = lstColDefs.Count;
                for (int iColIndex = 0; iColIndex < lstColDefs.Count; iColIndex++)
                {
                    thisColDef = (StagingColumnDefinition)lstColDefs[iColIndex];

                    // Get the column type.  If the type is "INPUT" OR "DESCRIPTION", then display the column.  Otherwise skip it.
                    cType = thisColDef.getType();
                    if ((cType == ColumnType.INPUT) || (cType == ColumnType.DESCRIPTION))
                    {
                        // Add a new column to the table data view
                        sColumnName  = "ColumnName";
                        sColumnName += iColIndex;
                        sColumnLabel = thisColDef.getName();
                        dataGridViewPicker.Columns.Add(sColumnName, sColumnLabel);
                        iNumColumnsUsed++;

                        // keep track of descrption columns
                        if (cType == ColumnType.DESCRIPTION)
                        {
                            lstDescriptionColumns.Add(iColIndex);
                        }

                        // Need to keep track of the first INPUT column.  That column contains the information we pass back if a user
                        // selects the row or cell.
                        if ((cType == ColumnType.INPUT) && (miInputCol == -1))
                        {
                            miInputCol = iNumColumnsUsed - 1;
                        }

                        dataGridViewPicker.Columns[iNumColumnsUsed - 1].DefaultCellStyle.WrapMode = DataGridViewTriState.True;
                        dataGridViewPicker.Columns[iNumColumnsUsed - 1].SortMode = DataGridViewColumnSortMode.NotSortable;
                    }
                }
            }


            // Set the widths of the columns in the datagridview.  Set the input column to be small and the description columns to be large
            //  We do this so that if we only have an input and description will fill the entire grid view (no veritical scrolling).
            //  If we have 2 or more desription fields, then we need to fit them all in.
            //
            int iWidthDivisor  = 0;
            int iViewableWidth = dataGridViewPicker.Width - 50; // remove size of input column

            if (iNumColumnsUsed > 1)
            {
                iWidthDivisor = (int)((double)iViewableWidth / (double)(iNumColumnsUsed - 1));
            }
            else
            {
                iWidthDivisor = 300;
            }
            for (int i = 0; i < dataGridViewPicker.Columns.Count; i++)
            {
                if (i == miInputCol)
                {
                    if (iNumColumnsUsed == 1)
                    {
                        dataGridViewPicker.Columns[i].Width = 300;
                    }
                    else
                    {
                        dataGridViewPicker.Columns[i].Width = 50;
                    }
                }
                else
                {
                    dataGridViewPicker.Columns[i].Width = iWidthDivisor;
                }
            }

            // Now loop through the table rows and add each cell to the table
            String sCellValue = "";

            for (int iRowIndex = 0; iRowIndex < iNumRows; iRowIndex++)
            {
                dataGridViewPicker.RowCount++;
                dataGridViewPicker.Rows[iRowIndex].Height = 40;

                for (int iColIndex = 0; iColIndex < iNumColumns; iColIndex++)
                {
                    thisColDef = (StagingColumnDefinition)lstColDefs[iColIndex];
                    cType      = thisColDef.getType();

                    if ((cType == ColumnType.INPUT) || (cType == ColumnType.DESCRIPTION))
                    {
                        sCellValue = thisTable.getRawRows()[iRowIndex][iColIndex];
                        dataGridViewPicker[iColIndex, iRowIndex].Value = sCellValue;
                    }
                }
            }

            // See if there are two or more description fields.  If so, see if we can find one
            // that has a label of "Description"
            miDescriptionColumn = -1;
            if (lstDescriptionColumns.Count > 1)
            {
                sColumnLabel = "";
                for (int iColIndex = 0; iColIndex < lstDescriptionColumns.Count; iColIndex++)
                {
                    sColumnLabel = ((StagingColumnDefinition)lstColDefs[lstDescriptionColumns[iColIndex]]).getName();
                    if (sColumnLabel == "Description")
                    {
                        miDescriptionColumn = lstDescriptionColumns[iColIndex];
                    }
                }
                if (miDescriptionColumn == -1)
                {
                    miDescriptionColumn = lstDescriptionColumns[0];
                }
            }
            else if (lstDescriptionColumns.Count == 0)
            {
                miDescriptionColumn = 0;  // for tables that do not have a description.  point to the code
            }
            else
            {
                miDescriptionColumn = lstDescriptionColumns[0];
            }
        }
        // Initialize a table.
        // @param table table entity
        // @return initialized table entity
        public static StagingTable initTable(StagingTable table)
        {
            HashSet <String> extraInputs = new HashSet <String>();

            List <List <String> > pTableRawRows = table.getRawRows();

            // empty out the parsed rows
            List <ITableRow> newTableRows = new List <ITableRow>();

            if (pTableRawRows != null)
            {
                newTableRows.Capacity = pTableRawRows.Count;
            }
            table.setTableRows(newTableRows);

            if (pTableRawRows != null)
            {
                foreach (List <String> row in pTableRawRows)
                {
                    StagingTableRow tableRowEntity = new StagingTableRow();

                    // make sure the number of cells in the row matches the number of columns defined
                    if (table.getColumnDefinitions().Count != row.Count)
                    {
                        throw new System.InvalidOperationException("Table '" + table.getId() + "' has a row with " + row.Count + " values but should have " + table.getColumnDefinitions().Count + ": " + row);
                    }

                    // loop over the column definitions in order since the data needs to be retrieved by array position
                    for (int i = 0; i < table.getColumnDefinitions().Count; i++)
                    {
                        StagingColumnDefinition col = (StagingColumnDefinition)(table.getColumnDefinitions()[i]);
                        String cellValue            = row[i];

                        switch (col.getType())
                        {
                        case ColumnType.INPUT:
                            // if there are no ranges in the list, that means the cell was "blank" and is not needed in the table row
                            List <Range> ranges = splitValues(cellValue);
                            if (!(ranges.Count == 0))
                            {
                                tableRowEntity.addInput(col.getKey(), ranges);

                                // if there are key references used (values that reference other inputs) like {{key}}, then add them to the extra inputs list
                                foreach (StagingRange range in ranges)
                                {
                                    if (DecisionEngineFuncs.isReferenceVariable(range.getLow()))
                                    {
                                        extraInputs.Add(DecisionEngineFuncs.trimBraces(range.getLow()));
                                    }
                                    if (DecisionEngineFuncs.isReferenceVariable(range.getHigh()))
                                    {
                                        extraInputs.Add(DecisionEngineFuncs.trimBraces(range.getHigh()));
                                    }
                                }
                            }
                            break;

                        case ColumnType.ENDPOINT:
                            StagingEndpoint endpoint = parseEndpoint(cellValue);
                            endpoint.setResultKey(col.getKey());
                            tableRowEntity.addEndpoint(endpoint);

                            // if there are key references used (values that reference other inputs) like {{key}}, then add them to the extra inputs list
                            if (EndpointType.VALUE == endpoint.getType() && DecisionEngineFuncs.isReferenceVariable(endpoint.getValue()))
                            {
                                extraInputs.Add(DecisionEngineFuncs.trimBraces(endpoint.getValue()));
                            }
                            break;

                        case ColumnType.DESCRIPTION:
                            // do nothing
                            break;

                        default:
                            throw new System.InvalidOperationException("Table '" + table.getId() + " has an unknown column type: '" + col.getType() + "'");
                        }
                    }

                    tableRowEntity.ConvertColumnInput();

                    newTableRows.Add(tableRowEntity);
                }
            }

            // add extra inputs, if any; do not include context variables since they are not user input
            foreach (String s in Staging.CONTEXT_KEYS)
            {
                extraInputs.Remove(s);
            }
            table.setExtraInput(extraInputs.Count == 0 ? null : extraInputs);

            table.GenerateInputColumnDefinitions();

            return(table);
        }