public virtual double GetNonReferentialProbability(Mention.MentionContext mention)
		{
			List<string> features = GetFeatures(mention);
			double probability = mModel.Evaluate(features.ToArray())[mNonReferentialIndex];
			if (mDebugOn)
			{
				System.Console.Error.WriteLine(this + " " + mention.ToText() + " ->  null " + probability + " " + string.Join(",", features.ToArray()));
			}
			return probability;
		}
        public override DiscourseEntity Retain(Mention.MentionContext mention, DiscourseModel discourseModel)
        {
            //System.err.println(this+".retain("+ec+") "+mode);
            if (mResolverMode == ResolverMode.Train)
            {
                DiscourseEntity discourseEntity = null;
                bool referentFound = false;
                bool hasReferentialCandidate = false;
                bool nonReferentFound = false;
                for (int entityIndex = 0; entityIndex < GetNumberEntitiesBack(discourseModel); entityIndex++)
                {
                    DiscourseEntity currentDiscourseEntity = discourseModel.GetEntity(entityIndex);
                    Mention.MentionContext entityMention = currentDiscourseEntity.LastExtent;
                    if (IsOutOfRange(mention, currentDiscourseEntity))
                    {
                        if (mention.Id != -1 && !referentFound)
                        {
                            //System.err.println("retain: Referent out of range: "+ec.toText()+" "+ec.parse.getSpan());
                        }
                        break;
                    }
                    if (IsExcluded(mention, currentDiscourseEntity))
                    {
                        if (ShowExclusions)
                        {
                            if (mention.Id != - 1 && entityMention.Id == mention.Id)
                            {
                                System.Console.Error.WriteLine(this + ".retain: Referent excluded: (" + mention.Id + ") " + mention.ToText() + " " + mention.IndexSpan + " -> (" + entityMention.Id + ") " + entityMention.ToText() + " " + entityMention.Span + " " + this);
                            }
                        }
                    }
                    else
                    {
                        hasReferentialCandidate = true;
                        bool useAsDifferentExample = defaultReferent(currentDiscourseEntity);
                        //if (!sampleSelection || (mention.getId() != -1 && entityMention.getId() == mention.getId()) || (!nonReferentFound && useAsDifferentExample)) {
                        List<string> features = GetFeatures(mention, currentDiscourseEntity);

                        //add Event to Model
                        if (mDebugOn)
                        {
                            System.Console.Error.WriteLine(this + ".retain: " + mention.Id + " " + mention.ToText() + " -> " + entityMention.Id + " " + currentDiscourseEntity);
                        }
                        if (mention.Id != - 1 && entityMention.Id == mention.Id)
                        {
                            referentFound = true;
                            mEvents.Add(new SharpEntropy.TrainingEvent(Same, features.ToArray()));
                            discourseEntity = currentDiscourseEntity;
                            //System.err.println("MaxentResolver.retain: resolved at "+ei);
                            Distances.Add(entityIndex);
                        }
                        else if (!mPairedSampleSelection || (!nonReferentFound && useAsDifferentExample))
                        {
                            nonReferentFound = true;
                            mEvents.Add(new SharpEntropy.TrainingEvent(Diff, features.ToArray()));
                        }
                        //}
                    }
                    if (mPairedSampleSelection && referentFound && nonReferentFound)
                    {
                        break;
                    }
                    if (mPreferFirstReferent && referentFound)
                    {
                        break;
                    }
                }
                // doesn't refer to anything
                if (hasReferentialCandidate)
                {
                    mNonReferentialResolver.AddEvent(mention);
                }
                return discourseEntity;
            }
            else
            {
                return base.Retain(mention, discourseModel);
            }
        }
        public override DiscourseEntity Resolve(Mention.MentionContext expression, DiscourseModel discourseModel)
        {
            DiscourseEntity discourseEntity;
            int entityIndex = 0;
            double nonReferentialProbability = mNonReferentialResolver.GetNonReferentialProbability(expression);
            if (mDebugOn)
            {
                System.Console.Error.WriteLine(this.ToString() + ".resolve: " + expression.ToText() + " -> " + "null " + nonReferentialProbability);
            }
            for (; entityIndex < GetNumberEntitiesBack(discourseModel); entityIndex++)
            {
                discourseEntity = discourseModel.GetEntity(entityIndex);
                if (IsOutOfRange(expression, discourseEntity))
                {
                    break;
                }
                if (IsExcluded(expression, discourseEntity))
                {
                    mCandidateProbabilities[entityIndex] = 0;
                    if (mDebugOn)
                    {
                        System.Console.Error.WriteLine("excluded " + this.ToString() + ".resolve: " + expression.ToText() + " -> " + discourseEntity + " " + mCandidateProbabilities[entityIndex]);
                    }
                }
                else
                {
                    string[] features = GetFeatures(expression, discourseEntity).ToArray();
                    try
                    {
                        mCandidateProbabilities[entityIndex] = mModel.Evaluate(features)[mSameIndex];
                    }
                    catch (System.IndexOutOfRangeException e)
                    {
                        mCandidateProbabilities[entityIndex] = 0;
                    }
                    if (mDebugOn)
                    {
                        System.Console.Error.WriteLine(this + ".resolve: " + expression.ToText() + " -> " + discourseEntity + " (" + expression.GetGender() + "," + discourseEntity.Gender + ") " + mCandidateProbabilities[entityIndex] + " " + string.Join(",", features)); //SupportClass.CollectionToString(lfeatures));
                    }
                }
                if (mPreferFirstReferent && mCandidateProbabilities[entityIndex] > nonReferentialProbability)
                {
                    entityIndex++; //update for nonRef assignment
                    break;
                }
            }
            mCandidateProbabilities[entityIndex] = nonReferentialProbability;

            // find max
            int maximumCandidateIndex = 0;
            for (int currentCandidate = 1; currentCandidate <= entityIndex; currentCandidate++)
            {
                if (mCandidateProbabilities[currentCandidate] > mCandidateProbabilities[maximumCandidateIndex])
                {
                    maximumCandidateIndex = currentCandidate;
                }
            }
            if (maximumCandidateIndex == entityIndex)
            {
                // no referent
                return null;
            }
            else
            {
                discourseEntity = discourseModel.GetEntity(maximumCandidateIndex);
                return discourseEntity;
            }
        }
 private string GetSemanticCompatibilityFeature(Mention.MentionContext entityContext, DiscourseEntity discourseEntity)
 {
     if (mSimilarityModel != null)
     {
         double best = 0;
         foreach (Mention.MentionContext checkEntityContext in discourseEntity.Mentions)
         {
             double sim = mSimilarityModel.AreCompatible(entityContext, checkEntityContext);
             if (mDebugOn)
             {
                 System.Console.Error.WriteLine("MaxentResolver.GetSemanticCompatibilityFeature: sem-compat " + sim + " " + entityContext.ToText() + " " + checkEntityContext.ToText());
             }
             if (sim > best)
             {
                 best = sim;
             }
         }
         if (best > mMinimumSimilarityProbability)
         {
             return mSimilarityCompatible;
         }
         else if (best > (1 - mMinimumSimilarityProbability))
         {
             return mSimilarityUnknown;
         }
         else
         {
             return mSimilarityIncompatible;
         }
     }
     else
     {
         System.Console.Error.WriteLine("MaxentResolver: Uninitialized Semantic Model");
         return mSimilarityUnknown;
     }
 }