/// <summary>
        /// PreExecute Phase for initialization of internal runtime structures
        /// </summary>
        public override void PreExecute()
        {
            bool fireAgain = true;

            rowsProcessed = 0;
            ComponentMetaData.FireInformation(0, this.ComponentMetaData.Name, "Pre-Execute phase is beginning.", string.Empty, 0, ref fireAgain);

            IDTSInput input = ComponentMetaData.InputCollection[0];

            inputBufferColumns = new List <InputBufferColumnInfo>(input.InputColumnCollection.Count);

            for (int i = 0; i < input.InputColumnCollection.Count; i++)
            {
                IDTSInputColumn column = input.InputColumnCollection[i];

                inputBufferColumns.Add(new InputBufferColumnInfo(BufferManager.FindColumnByLineageID(input.Buffer, column.LineageID),
                                                                 column.Name, column.ID, column.LineageID, 0, column.DataType, column.Length, column.Precision, column.Scale));
            }

            outputColumns = new List <XmlColumn>();
            IDTSOutput output = ComponentMetaData.OutputCollection[0];

            foreach (IDTSOutputColumn col in output.OutputColumnCollection)
            {
                SaveOptions saveOptions       = SaveOptions.None;
                bool        serializeDataType = false;
                bool        serializeLineage  = false;
                string      sourceID          = string.Empty;
                string      sourceName        = string.Empty;
                List <int>  cols = null;

                foreach (IDTSCustomProperty prop in col.CustomPropertyCollection)
                {
                    if (prop.Name == Resources.XmlSaveOptionPropertyName)
                    {
                        saveOptions = (SaveOptions)prop.Value;
                    }
                    else if (prop.Name == Resources.XmlSerializeDataTypeName)
                    {
                        serializeDataType = (bool)prop.Value;
                    }
                    else if (prop.Name == Resources.XmlSerializeLineageName)
                    {
                        serializeLineage = (bool)prop.Value;
                    }
                    else if (prop.Name == Resources.XmlInputColumnsPropertyname)
                    {
                        string colsStr     = prop.Value.ToString();
                        var    colLineages = InputColumns.ParseInputLineages(colsStr);

                        cols = new List <int>(colLineages.Count);

                        foreach (int lineageID in colLineages)
                        {
                            int idx = inputBufferColumns.FindIndex(ibci => ibci.LineageID == lineageID);
                            cols.Add(idx);
                        }
                    }
                    else if (prop.Name == Resources.XmlSourceIdPropertyName)
                    {
                        sourceName = prop.Value.ToString();
                    }
                    else if (prop.Name == Resources.XmlSourceNamePropertyName)
                    {
                        sourceID = prop.Value.ToString();
                    }
                }

                int index = BufferManager.FindColumnByLineageID(input.Buffer, col.LineageID);
                outputColumns.Add(new XmlColumn(index, col.Name, col.DataType, saveOptions, serializeLineage, serializeDataType, cols, sourceID, sourceName, col.Length));
            }
        }
        /// <summary>
        /// Validate HashColumnsTransform metadata
        /// </summary>
        /// <returns></returns>
        public override DTSValidationStatus Validate()
        {
            if (ComponentMetaData.InputCollection.Count != 1)
            {
                FireComponentMetadataError(0, Resources.ErrorIncorrectNumberOfInputs);
                return(DTSValidationStatus.VS_NEEDSNEWMETADATA);
            }

            if (ComponentMetaData.OutputCollection.Count != 1)
            {
                FireComponentMetadataError(0, Resources.ErrorIncorrectNumberOfOutputs);
                return(DTSValidationStatus.VS_NEEDSNEWMETADATA);
            }

            IDTSInput        input  = ComponentMetaData.InputCollection[0];
            IDTSVirtualInput vInput = input.GetVirtualInput();

            foreach (IDTSInputColumn column in input.InputColumnCollection)
            {
                try
                {
                    IDTSVirtualInputColumn100 vColumn = vInput.VirtualInputColumnCollection.GetVirtualInputColumnByLineageID(column.LineageID);
                }
                catch
                {
                    FireComponentMetadataError(0, string.Format(Resources.ErrorInputColumnNotInUpstreamComponent, column.IdentificationString));
                    inputColumnsValid = false;
                    return(DTSValidationStatus.VS_NEEDSNEWMETADATA);
                }
            }

            IDTSOutput output = ComponentMetaData.OutputCollection[0];
            List <IDTSOutputColumn> redundantColumns = new List <IDTSOutputColumn>(output.OutputColumnCollection.Count);
            bool       xmlColumnExists      = false;
            List <int> missingLineages      = new List <int>();
            List <int> missingInputLineages = new List <int>();
            bool       missingError         = false;

            foreach (IDTSOutputColumn outputColumn in output.OutputColumnCollection)
            {
                bool isRendundant  = true;
                bool isInputColumn = false;
                foreach (IDTSInputColumn inputColumn in input.InputColumnCollection)
                {
                    if (inputColumn.Name == outputColumn.Name)
                    {
                        isRendundant  = false;
                        isInputColumn = true;
                        break;
                    }
                }


                //Check if XML Column;
                if (!isInputColumn)
                {
                    foreach (IDTSCustomProperty prop in outputColumn.CustomPropertyCollection)
                    {
                        if (prop.Name == Resources.XmlInputColumnsPropertyname)
                        {
                            isRendundant    = false;
                            xmlColumnExists = true;

                            var lineages = InputColumns.ParseInputLineages(prop.Value.ToString());

                            foreach (IDTSInputColumn icol in input.InputColumnCollection)
                            {
                                int l = icol.LineageID;
                                lineages.Remove(l);
                                if (lineages.Count == 0)
                                {
                                    break;
                                }
                            }

                            if (lineages.Count > 0)
                            {
                                foreach (int l in lineages)
                                {
                                    if (!missingInputLineages.Contains(l))
                                    {
                                        missingInputLineages.Add(l);
                                    }
                                }

                                foreach (IDTSVirtualInputColumn vcol in vInput.VirtualInputColumnCollection)
                                {
                                    int l = vcol.LineageID;
                                    lineages.Remove(l);
                                    if (lineages.Count == 0)
                                    {
                                        break;
                                    }
                                }

                                if (lineages.Count > 0)
                                {
                                    foreach (int l in lineages)
                                    {
                                        if (!missingLineages.Contains(l))
                                        {
                                            missingLineages.Add(l);
                                        }
                                    }
                                }
                            }
                        }
                        if (prop.Name == Resources.XmlSaveOptionPropertyName)
                        {
                            isRendundant    = false;
                            xmlColumnExists = true;

                            if (!Enum.IsDefined(typeof(SaveOptions), prop.Value))
                            {
                                FireComponentMetadataError(0, string.Format(Resources.ErrorInvalidSaveOption, outputColumn.Name));
                                return(DTSValidationStatus.VS_NEEDSNEWMETADATA);
                            }
                            else
                            {
                                if (outputColumn.DataType != DataType.DT_NTEXT && outputColumn.DataType != DataType.DT_WSTR)
                                {
                                    FireComponentMetadataError(0, string.Format(Resources.ErrorInvalidDataType, outputColumn.Name));
                                    return(DTSValidationStatus.VS_NEEDSNEWMETADATA);
                                }
                            }
                        }
                    }
                }

                //add redundand column to redundand list
                if (isRendundant)
                {
                    redundantColumns.Add(outputColumn);
                }
            }


            if (missingLineages.Count > 0)
            {
                string ml = string.Join(", ", missingLineages.ConvertAll <string>(l => l.ToString()).ToArray());

                FireComponentMetadataError(0, string.Format("Output columns are referencing input column lineages which do not exists: {0}", ml));
                missingError = true;
            }

            if (missingInputLineages.Count > 0)
            {
                string ml = string.Join(", ", missingInputLineages.ConvertAll <string>(l => l.ToString()).ToArray());

                FireComponentMetadataError(0, string.Format("Output columns are referencing input column lineages which are not selected as Input columns: {0}", ml));
                missingError = true;
            }

            if (missingError)
            {
                return(DTSValidationStatus.VS_NEEDSNEWMETADATA);
            }



            //remove redundand output columns
            foreach (IDTSOutputColumn col in redundantColumns)
            {
                output.OutputColumnCollection.RemoveObjectByID(col.ID);
            }

            //If XmlColumn does not exists, create a default one
            if (!xmlColumnExists)
            {
                IDTSOutputColumn xmlCol = output.OutputColumnCollection.New();
                xmlCol.Name        = Resources.XmlColumnDefaultName;
                xmlCol.Description = Resources.XmlColumnDefaultDesccription;

                SetXmlColumnProperties(xmlCol);
            }

            return(DTSValidationStatus.VS_ISVALID);
        }