private MamdaOptionContract findContract(
            MamdaSubscription subscription,
            MamaMsg msg)
        {
            /*
             * NOTE: fields which are enums can be pubished as integers if feedhandler
             * uses mama-publish-enums-as-ints.  It may also be possible for a feed to
             * publish the numerical value as a string. All enumerated fields must be handled
             * by getting the value based on the field type.
             */

            // Look up the strike price and expiration date
            string contractSymbol = null;

            if (!msg.tryString(MamdaOptionFields.CONTRACT_SYMBOL, ref contractSymbol))
            {
                throw new MamdaDataException("cannot find contract symbol");
            }

            string fullSymbol            = contractSymbol;
            MamdaOptionContract contract = mChain.getContract(fullSymbol);

            if (contract == null)
            {
                string expireDateStr = String.Empty;
                double strikePrice   = 0.0;
                string putCall       = String.Empty;
                uint   openInterest  = 0;

                msg.tryString(MamdaOptionFields.EXPIRATION_DATE, ref expireDateStr);
                msg.tryF64(MamdaOptionFields.STRIKE_PRICE, ref strikePrice);

                if (msg.tryField(MamdaOptionFields.PUT_CALL, ref tmpfield_))
                {
                    putCall = getFieldAsString(tmpfield_);
                }

                int    symbolLen = fullSymbol.Length;
                string symbol    = null;
                string exchange  = null;
                int    dotIndex  = fullSymbol.LastIndexOf('.');
                if (dotIndex > 0)
                {
                    // Have exchange in symbol.
                    exchange = fullSymbol.Substring(dotIndex + 1);
                    symbol   = fullSymbol.Substring(0, dotIndex);
                }
                else
                {
                    exchange = "";
                    symbol   = fullSymbol;
                }

                DateTime expireDate = DateTime.MinValue;
                try
                {
                    expireDate = mDateFormat.Parse(expireDateStr);
                }
                catch (FormatException e)
                {
                    throw new MamdaDataException(
                              String.Format("cannot parse expiration date: {0}", expireDateStr));
                }

                MamdaOptionContract.PutOrCall putCallchar = extractPutCall(msg, fullSymbol);
                contract = new MamdaOptionContract(
                    symbol,
                    exchange,
                    expireDate,
                    strikePrice,
                    putCallchar);

                MamdaOptionContract.ExerciseStyle exerciseStyleChar = extractExerciseStyle(msg, fullSymbol);
                contract.setExerciseStyle(exerciseStyleChar);


                if (msg.tryU32(MamdaOptionFields.OPEN_INTEREST, ref openInterest))
                {
                    contract.setOpenInterest((long)openInterest);
                }

                mChain.addContract(fullSymbol, contract);

                mLastActionContract           = contract;
                mLastActionContractFieldState = MamdaFieldState.MODIFIED;
                mLastAction           = MamdaOptionAction.Add;
                mLastActionFieldState = MamdaFieldState.MODIFIED;
                foreach (MamdaOptionChainHandler handler in mHandlers)
                {
                    handler.onOptionContractCreate(subscription, this, msg, contract, mChain);
                }
            }
            return(contract);
        }
        private MamdaOptionContract.ExerciseStyle extractExerciseStyle(
            MamaMsg msg,
            string fullSymbol)
        {
            MamdaOptionContract.ExerciseStyle exerciseStyle = MamdaOptionContract.ExerciseStyle.Unknown;
            int exerciseStyleInt = 0;

            if (!msg.tryField(MamdaOptionFields.EXERCISE_STYLE, ref tmpfield_))
            {
                Console.WriteLine("findContract:CANNOT find exercisestyle in msg:" + fullSymbol + exerciseStyle);
            }
            else
            {
                switch (tmpfield_.getType())
                {
                case mamaFieldType.MAMA_FIELD_TYPE_I8:
                case mamaFieldType.MAMA_FIELD_TYPE_U8:
                case mamaFieldType.MAMA_FIELD_TYPE_I16:
                case mamaFieldType.MAMA_FIELD_TYPE_U16:
                    exerciseStyleInt = tmpfield_.getU16();
                    switch (exerciseStyleInt)
                    {
                    case 1:
                        exerciseStyle = MamdaOptionContract.ExerciseStyle.American;
                        break;

                    case 2:
                        exerciseStyle = MamdaOptionContract.ExerciseStyle.European;
                        break;

                    case 3:
                        exerciseStyle = MamdaOptionContract.ExerciseStyle.Capped;
                        break;

                    case 99:
                        exerciseStyle = MamdaOptionContract.ExerciseStyle.Unknown;
                        break;

                    default:
                        exerciseStyle = MamdaOptionContract.ExerciseStyle.Unknown;
                        Console.Write("Unhandled value for wExerciseStyle." + exerciseStyleInt);
                        break;
                    }
                    break;

                case mamaFieldType.MAMA_FIELD_TYPE_STRING:
                    string exerciseStyleStr = tmpfield_.getString();;
                    switch (exerciseStyleStr[0])
                    {
                    case '1':
                    case 'A':
                        exerciseStyle = MamdaOptionContract.ExerciseStyle.American;
                        break;

                    case '2':
                    case 'E':
                        exerciseStyle = MamdaOptionContract.ExerciseStyle.European;
                        break;

                    case '3':
                    case 'C':
                        exerciseStyle = MamdaOptionContract.ExerciseStyle.Capped;
                        break;

                    default:
                        exerciseStyle = MamdaOptionContract.ExerciseStyle.Unknown;
                        if ((exerciseStyleStr == "99") && (exerciseStyleStr == "Z"))
                        {
                            Console.WriteLine("Unhandled value for wExerciseStyle." + exerciseStyleStr);
                        }
                        break;
                    }
                    break;

                default:
                    exerciseStyle = MamdaOptionContract.ExerciseStyle.Unknown;
                    Console.WriteLine("Unhandled type for wExerciseStyle. Expected string or integer but returned:" + tmpfield_.getType());
                    break;
                }
            }
            return(exerciseStyle);
        }