public PropertyMetaData(
     PropertyInfo propertyInfo, 
     AoMemberAttribute memberAttribute, 
     AoFlagsAttribute flagsAttribute, 
     AoUsesFlagsAttribute[] usesFlagsAttributes)
 {
     this.propertyInfo = propertyInfo;
     this.flagsAttribute = flagsAttribute;
     this.usesFlagsAttributes = usesFlagsAttributes;
     this.options = new MemberOptions(
         this.propertyInfo.PropertyType, 
         memberAttribute.IsFixedSize, 
         memberAttribute.FixedSizeLength, 
         memberAttribute.SerializeSize, 
         memberAttribute.PadAfter, 
         memberAttribute.PadBefore, 
         usesFlagsAttributes);
 }
 private bool EvaluateHasAny(AoUsesFlagsAttribute usesFlags)
 {
     var flagValue = this.GetFlagValue(usesFlags.Flag);
     return (flagValue & usesFlags.CriteriaValue) > 0;
 }
 private bool EvaluateHasNone(AoUsesFlagsAttribute usesFlags)
 {
     var flagValue = this.GetFlagValue(usesFlags.Flag);
     return usesFlags.CriteriaValues.All(v => (v & flagValue) == 0);
 }
 private bool EvaluateEqualsToAny(AoUsesFlagsAttribute usesFlags)
 {
     var flagValue = this.GetFlagValue(usesFlags.Flag);
     return usesFlags.CriteriaValues.Any(v => v == flagValue);
 }
 private bool Evaluate(AoUsesFlagsAttribute usesFlags)
 {
     switch (usesFlags.Criteria)
     {
         case FlagsCriteria.HasAll:
             return this.EvaluateHasAll(usesFlags);
         case FlagsCriteria.HasAny:
             return this.EvaluateHasAny(usesFlags);
         case FlagsCriteria.EqualsToAny:
             return this.EvaluateEqualsToAny(usesFlags);
         case FlagsCriteria.HasNone:
             return this.EvaluateHasNone(usesFlags);
         case FlagsCriteria.Default:
             return true;
         default:
             throw new ArgumentOutOfRangeException();
     }
 }