Buggy code:
public class RandomizedGreedyDecoder implements Decoder { DiscriminitiveCKYSampler sampler ; WordEnumeration wordEnum ; LabelEnumeration labels ; RuleEnumeration rules ; GreedyChange greedyChange ; FirstOrderFeatureHolder firstOrderFeatures ; class SpanAndParent { Span span ; int parentLabel ; public SpanAndParent ( Span s , int parentLabel ) { } @ Override public int hashCode ( ) { } @ Override public boolean equals ( Object other ) { } } HashMap < Span , Double > firstOrderSpanScoreCache ; boolean doSecondOrder = true ; boolean costAugmenting = false ; int [ ] [ ] goldLabels ; int numberSampleIterations = 50 ; public RandomizedGreedyDecoder ( WordEnumeration words , LabelEnumeration labels , RuleEnumeration rules ) { } public void samplerDoCounts ( List < SpannedWords > trainingData ) { } public void setSecondOrder ( boolean secondOrder ) { } public void setCostAugmenting ( boolean costAugmenting , SpannedWords gold ) { } public void setNumberSampleIterations ( int iterations ) { } double lastScore = 0 ; public List < Span > decode ( List < Integer > words , FeatureParameters params , boolean dropout ) { <START_BUG> firstOrderSpanScoreCache = new HashMap < Span , Double > ( 1000 ) ; <END_BUG> firstOrderFeatures . fillScoreArrays ( words , params , dropout ) ; sampler . setCostAugmenting ( costAugmenting , goldLabels ) ; sampler . calculateProbabilities ( words ) ; Set < Set < Span > > alreadyDone = new HashSet < > ( ) ; List < Span > best = new ArrayList < Span > ( ) ; double bestScore = Double . NEGATIVE_INFINITY ; int numberOfUpdates = 0 ; for ( int iteration = 0 ; ( iteration < ( numberSampleIterations ) ) && ( numberOfUpdates < ( numberSampleIterations ) ) ; iteration ++ ) { List < Span > spans = sampler . sample ( ) ; if ( ( spans . size ( ) ) > 0 ) { SpanUtilities . checkCorrectness ( spans ) ; boolean changed = true ; double lastScore = Double . NEGATIVE_INFINITY ; while ( changed ) { Set < Span > spansSet = new HashSet ( spans ) ; if ( alreadyDone . contains ( spansSet ) ) break ; else alreadyDone . add ( spansSet ) ; numberOfUpdates ++ ; double score = score ( words , spans , params , dropout ) ; if ( score <= lastScore ) { changed = false ; } lastScore = score ; for ( int i = 0 ; i < ( words . size ( ) ) ; i ++ ) { List < ParentedSpans > options = greedyChange . makeGreedyLabelChanges ( spans , i , ( i + 1 ) , false ) ; spans = getMax ( options , words , params , dropout ) ; } for ( int length = 1 ; length < ( ( words . size ( ) ) + 1 ) ; length ++ ) { for ( int start = 0 ; start < ( ( ( words . size ( ) ) - length ) + 1 ) ; start ++ ) { boolean exists = false ; for ( int i = 0 ; i < ( spans . size ( ) ) ; i ++ ) { Span s = spans . get ( i ) ; if ( ( ( s . getStart ( ) ) == start ) && ( ( s . getEnd ( ) ) == ( start + length ) ) ) { exists = true ; } } if ( exists ) { List < ParentedSpans > update = greedyChange . makeGreedyChanges ( spans , start , ( start + length ) ) ; spans = getMax ( update , words , params , dropout ) ; } } } List < ParentedSpans > options = greedyChange . makeGreedyLabelChanges ( spans , 0 , words . size ( ) , true ) ; spans = getMax ( options , words , params , dropout ) ; } } double score = score ( words , spans , params , dropout ) ; if ( score > bestScore ) { best = new ArrayList ( spans ) ; bestScore = score ; } } lastScore = bestScore ; return best ; } public double getLastScore ( ) { } public List < Span > decodeNoGreedy ( List < Integer > words , FeatureParameters params , boolean dropout ) { } private List < Span > getMax ( List < ParentedSpans > options , List < Integer > words , FeatureParameters params , boolean dropout ) { } private double score ( List < Integer > words , List < Span > spans , FeatureParameters params , boolean dropout ) { } double score ( List < Integer > words , List < Span > spans , int [ ] parents , FeatureParameters params , boolean dropout ) { } }

Fix:
firstOrderSpanScoreCache = new HashMap < Span , Double > ( 30000 , 0.5F ) ;