/// <summary>
 /// Gets the type.
 /// </summary>
 /// <param name="field">The field.</param>
 /// <returns>Type.</returns>
 /// <exception cref="System.ArgumentException">Field type not supported.;field</exception>
 private static Type GetType(FieldInfo field)
 {
     return GetType(field.ColumnType);
 }
 private static NodeDataType GetDataType(FieldInfo field)
 {
     return GetDataType(field.ColumnType);
 }
        private static bool CanBeDestinationField(FieldInfo field)
        {
            if (field.IsReadOnly)
            {
                return false;
            }

            switch (field.ColumnType)
            {
                case ColumnTypes.Integer:
                case ColumnTypes.String:
                case ColumnTypes.Numeric:
                case ColumnTypes.Double:
                case ColumnTypes.Boolean:
                case ColumnTypes.DateTime:
                case ColumnTypes.SampleType:
                case ColumnTypes.Reference:
                case ColumnTypes.Result:
                case ColumnTypes.Sample:
                case ColumnTypes.Checklist:
                    return true;

                default:
                    return false;
            }
        }
        private static DestinationField CreateDestinationField(FieldInfo field, ExpressionObjectBase owner)
        {
            switch (field.ColumnType)
            {
                case ColumnTypes.Integer:
                case ColumnTypes.String:
                case ColumnTypes.Numeric:
                case ColumnTypes.Double:
                case ColumnTypes.Boolean:
                case ColumnTypes.DateTime:
                case ColumnTypes.SampleType:
                case ColumnTypes.Reference:
                case ColumnTypes.Result:
                case ColumnTypes.Sample:
                case ColumnTypes.Checklist:
                    {
                        var dataType = GetDataType(field);
                        var df = new DestinationField(owner)
                                     {
                                         DataType = dataType,
                                         Name = field.Name,
                                         ConnectorIn = { DataType = dataType, Name = field.Name },
                                         SetName = SourceFieldSetNames.DataTriggerDestinationItem,
                                         InnerName = field.SystemName,
                                         SystemName = field.SystemName
                                     };

                        return df;
                    }

                default:
                    throw new ArgumentException("Field type not supported.", "field");
            }
        }
        /// <summary>
        /// Creates the cross reference source field.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <param name="owner">The owner.</param>
        /// <returns>SourceField.</returns>
        private static SourceField CreateCrossReferenceSourceField(FieldInfo field, string processName, ExpressionObjectBase owner)
        {
            var dataType = field.ColumnType == ColumnTypes.Reference
                               ? NodeDataType.CrossReference
                               : NodeDataType.List;

            var sf = new SourceField(owner)
            {
                DataType = dataType,
                Name = field.Name,
                ConnectorOut = { DataType = dataType, Name = field.Name },
                SystemName = field.SystemName,
                SetName = SourceFieldSetNames.DataTriggerSourceItem,
                SubfieldsRetriever = new CrossReferenceSubfieldsRetriever(field, CanBeSourceField, CreateSourceField)
            };

            if (dataType == NodeDataType.CrossReference)
            {
                PublishedProcessInfo.BeginGetProcessInfoByCrossReferenceField(processName, field.SystemName, true,
                    result =>
                    {
                        if (result.Error == null &&
                            result.Object != null)
                        {
                            sf.AdditionalInfo = new CrossReferenceFieldInfo(result.Object.SystemName);
                        }
                    });
            }

            return sf;
        }
        /// <summary>
        /// Creates the file source field.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <param name="owner">The owner.</param>
        /// <returns>SourceField.</returns>
        private static SourceField CreateFileSourceField(FieldInfo field, ExpressionObjectBase owner)
        {
            const NodeDataType DataType = NodeDataType.File;

            var sf = new SourceField(owner)
            {
                DataType = DataType,
                Name = field.Name,
                ConnectorOut = { DataType = DataType, Name = field.Name },
                SystemName = field.SystemName,
                SetName = SourceFieldSetNames.DataTriggerSourceItem,
                SubfieldsRetriever = new FileSubfieldsRetriever(SourceFieldSetNames.DataTriggerSourceItem)
            };

            return sf;
        }
        /// <summary>
        /// Creates the source field.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <param name="owner">The owner.</param>
        /// <returns>SourceField.</returns>
        /// <exception cref="System.ArgumentException">Field type not supported.;field</exception>
        private static SourceField CreateSourceField(FieldInfo field, string processName, ExpressionObjectBase owner)
        {
            switch (field.FieldType.ColumnType)
            {
                case ColumnTypes.Integer:
                case ColumnTypes.String:
                case ColumnTypes.Numeric:
                case ColumnTypes.Double:
                case ColumnTypes.Boolean:
                case ColumnTypes.DateTime:
                case ColumnTypes.AutoNumber:
                case ColumnTypes.SampleType:
                case ColumnTypes.Label:
                    return CreateGenericSourceField(field, owner);

                case ColumnTypes.Reference:
                case ColumnTypes.MultiReference:
                    return CreateCrossReferenceSourceField(field, processName, owner);

                case ColumnTypes.File:
                    return CreateFileSourceField(field, owner);

                default:
                    throw new ArgumentException("Field type not supported.", "field");
            }
        }
        /// <summary>
        /// Creates the generic source field.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <param name="owner">The owner.</param>
        /// <returns>SourceField.</returns>
        private static SourceField CreateGenericSourceField(FieldInfo field, ExpressionObjectBase owner)
        {
            var dataType = SourceNodeFactory.GetDataType(GetType(field));

            var sf = new SourceField(owner)
            {
                DataType = dataType,
                Name = field.Name,
                ConnectorOut = { DataType = dataType, Name = field.Name },
                SetName = SourceFieldSetNames.DataTriggerSourceItem,
                InnerName = field.SystemName,
                SystemName = field.SystemName
            };

            return sf;
        }
 /// <summary>
 /// Determines whether this instance [can be source field] the specified field.
 /// </summary>
 /// <param name="field">The field.</param>
 /// <returns><c>true</c> if this instance [can be source field] the specified field; otherwise, <c>false</c>.</returns>
 private static bool CanBeSourceField(FieldInfo field)
 {
     switch (field.ColumnType)
     {
         case ColumnTypes.Integer:
         case ColumnTypes.String:
         case ColumnTypes.Reference:
         case ColumnTypes.MultiReference:
         case ColumnTypes.Numeric:
         case ColumnTypes.Double:
         case ColumnTypes.Boolean:
         case ColumnTypes.DateTime:
         case ColumnTypes.AutoNumber:
         case ColumnTypes.SampleType:
         case ColumnTypes.Label:
         case ColumnTypes.File:
             return true;
         default:
             return false;
     }
 }
        private IExpressionFieldsRetriever GetDestinationFieldsRetriever(FieldInfo field)
        {
            switch (field.FieldType.ColumnType)
            {
                case ColumnTypes.Reference:
                case ColumnTypes.MultiReference:
                    return new CrossReferenceSubfieldsRetriever(field, CanBeDestinationField, CreateDestinationField);

                case ColumnTypes.File:
                    return new FileSubfieldsRetriever(CreateConnectionValidator);

                case ColumnTypes.Checklist:
                    return new ChecklistSubfieldsRetriever(field, CanBeDestinationField, CreateDestinationField);

                case ColumnTypes.Sample:
                    return new SampleSubfieldsRetriever(CreateConnectionValidator);

                default:
                    return null;
            }
        }
        /// <summary>
        /// Creates the destination field.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <param name="owner">The owner.</param>
        /// <returns>The DestinationField.</returns>
        /// <exception cref="System.InvalidOperationException">Invalid destination field.</exception>
        private DestinationField CreateDestinationField(FieldInfo field, ExpressionObjectBase owner)
        {
            if (!CanBeDestinationField(field))
                throw new InvalidOperationException("Invalid destination field.");

            var dataType = GetNodeDataType(field);

            var result = new DestinationField(owner)
                             {
                                 DataType = dataType,
                                 Name = field.Name,
                                 IsKeyVisible = true,
                                 IsKeyEnabled = CanBeKeyField(field),
                                 ConnectorIn = { DataType = dataType, Name = field.Name },
                                 SystemName = field.SystemName,
                                 SetName = SourceFieldSetNames.Item,
                                 SubfieldsRetriever = GetDestinationFieldsRetriever(field)
                             };

            result.ConnectorIn.Validator = CreateConnectionValidator(result);

            return result;
        }
        /// <summary>
        /// Determines whether this instance [can be key field] the specified field.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <returns><c>true</c> if this instance [can be key field] the specified field; otherwise, <c>false</c>.</returns>
        private static bool CanBeKeyField(FieldInfo field)
        {
            if (!CanBeDestinationField(field))
                return false;

            switch (field.ColumnType)
            {
                case ColumnTypes.Integer:
                case ColumnTypes.String:
                case ColumnTypes.Reference:
                case ColumnTypes.Numeric:
                case ColumnTypes.Boolean:
                case ColumnTypes.DateTime:
                case ColumnTypes.Double:
                    return true;
            }

            return false;
        }
 /// <summary>
 /// Determines whether this instance [can be destination field] the specified field.
 /// </summary>
 /// <param name="field">The field.</param>
 /// <returns><c>true</c> if this instance [can be destination field] the specified field; otherwise, <c>false</c>.</returns>
 private static bool CanBeDestinationField(FieldInfo field)
 {
     return !field.IsCalculated && CanBeDestinationField(field.ColumnType);
 }