private void CheckPossibleValueInUnion(object value, ICustomAttributeProvider provider)
        {
            string switchExpr;

            if (provider == null || !MarshalingDescriptor.TryGetAttribute <string>(
                    provider, typeof(SwitchAttribute), "expr",
                    out switchExpr))
            {
                throw new InvalidOperationException(String.Format(
                                                        CultureInfo.InvariantCulture,
                                                        "cannot find switch attribute for union '{0}'",
                                                        value.GetType().Name));
            }

            Type type          = value.GetType();
            var  fieldsToCheck = new List <FieldInfo>();
            var  defaultFields = new List <FieldInfo>();

            foreach (var field in type.GetFields())
            {
                string caseExpr;


                if (MarshalingDescriptor.TryGetAttribute <string>(field,
                                                                  typeof(CaseAttribute), "expr", out caseExpr))
                {
                    IList <int?> caseValues = marshaler.EvaluateConstant(caseExpr);

                    int switchValue = marshaler.Evaluate(switchExpr);

                    if (caseValues.Contains(switchValue))
                    {
                        fieldsToCheck.Add(field);
                    }
                }
                else if (field.GetCustomAttributes(typeof(CaseDefaultAttribute), false).Length != 0)
                {
                    defaultFields.Add(field);
                }
            }

            if (fieldsToCheck.Count == 0)
            {
                fieldsToCheck.AddRange(defaultFields);
            }

            foreach (var field in fieldsToCheck)
            {
                object fieldValue = field.GetValue(value);
                if (IsStruct(field.GetType()))
                {
                    CheckPossibleValue(fieldValue, field);
                }
                else if (HasPossibleValue(field))
                {
                    CheckFieldValue(fieldValue, field);
                }
            }
        }