Buggy code:
public class RingGroupUpdateTransitionFunctionImpl implements RingGroupUpdateTransitionFunction { private static Logger LOG = Logger . getLogger ( RingGroupUpdateTransitionFunctionImpl . class ) ; @ Override public void manageTransitions ( RingGroup ringGroup ) throws IOException { boolean anyUpdatesPending = false ; boolean anyDownOrUpdating = false ; Queue < Ring > downable = new LinkedList < Ring > ( ) ; for ( Ring ring : ringGroup . getRings ( ) ) { <START_BUG> if ( Rings . isUpdatePending ( ring ) ) { <END_BUG> anyUpdatesPending = true ; RingGroupUpdateTransitionFunctionImpl . LOG . info ( ( ( ( ( ( ( "Ring<seq2seq4repair_space>" + ( ring . getRingNumber ( ) ) ) + "<seq2seq4repair_space>is<seq2seq4repair_space>updating<seq2seq4repair_space>to<seq2seq4repair_space>version<seq2seq4repair_space>" ) + ( ring . getUpdatingToVersionNumber ( ) ) ) + "<seq2seq4repair_space>and<seq2seq4repair_space>is<seq2seq4repair_space>" ) + ( ring . getState ( ) ) ) + "." ) ) ; switch ( ring . getState ( ) ) { case UP : RingGroupUpdateTransitionFunctionImpl . LOG . info ( ( ( "Ring<seq2seq4repair_space>" + ( ring . getRingNumber ( ) ) ) + "<seq2seq4repair_space>is<seq2seq4repair_space>a<seq2seq4repair_space>candidate<seq2seq4repair_space>for<seq2seq4repair_space>being<seq2seq4repair_space>taken<seq2seq4repair_space>down." ) ) ; downable . add ( ring ) ; break ; case GOING_DOWN : anyDownOrUpdating = true ; int numHostsIdle = Rings . getHostsInState ( ring , IDLE ) . size ( ) ; if ( numHostsIdle == ( ring . getHosts ( ) . size ( ) ) ) { RingGroupUpdateTransitionFunctionImpl . LOG . info ( ( ( ( ( "Ring<seq2seq4repair_space>" + ( ring . getRingNumber ( ) ) ) + "<seq2seq4repair_space>is<seq2seq4repair_space>currently<seq2seq4repair_space>" ) + ( ring . getState ( ) ) ) + ",<seq2seq4repair_space>and<seq2seq4repair_space>has<seq2seq4repair_space>nothing<seq2seq4repair_space>but<seq2seq4repair_space>IDLE<seq2seq4repair_space>or<seq2seq4repair_space>OFFLINE<seq2seq4repair_space>hosts.<seq2seq4repair_space>It's<seq2seq4repair_space>down!" ) ) ; ring . setState ( DOWN ) ; } else { RingGroupUpdateTransitionFunctionImpl . LOG . info ( String . format ( ( ( "Ring<seq2seq4repair_space>%d<seq2seq4repair_space>is<seq2seq4repair_space>currently<seq2seq4repair_space>" + ( ring . getState ( ) ) ) + ",<seq2seq4repair_space>but<seq2seq4repair_space>has<seq2seq4repair_space>only<seq2seq4repair_space>%d<seq2seq4repair_space>idle<seq2seq4repair_space>hosts,<seq2seq4repair_space>so<seq2seq4repair_space>it<seq2seq4repair_space>isn't<seq2seq4repair_space>fully<seq2seq4repair_space>DOWN<seq2seq4repair_space>yet." ) , ring . getRingNumber ( ) , numHostsIdle ) ) ; break ; } case DOWN : anyDownOrUpdating = true ; RingGroupUpdateTransitionFunctionImpl . LOG . info ( ( ( ( ( "Ring<seq2seq4repair_space>" + ( ring . getRingNumber ( ) ) ) + "<seq2seq4repair_space>is<seq2seq4repair_space>" ) + ( ring . getState ( ) ) ) + ",<seq2seq4repair_space>so<seq2seq4repair_space>we're<seq2seq4repair_space>going<seq2seq4repair_space>to<seq2seq4repair_space>start<seq2seq4repair_space>UPDATING." ) ) ; Rings . commandAll ( ring , EXECUTE_UPDATE ) ; ring . setState ( UPDATING ) ; break ; case UPDATING : anyDownOrUpdating = true ; int numHostsUpdating = Rings . getHostsInState ( ring , HostState . UPDATING ) . size ( ) ; if ( numHostsUpdating > 0 ) { RingGroupUpdateTransitionFunctionImpl . LOG . info ( ( ( ( ( "Ring<seq2seq4repair_space>" + ( ring . getRingNumber ( ) ) ) + "<seq2seq4repair_space>still<seq2seq4repair_space>has<seq2seq4repair_space>" ) + numHostsUpdating ) + "<seq2seq4repair_space>UPDATING<seq2seq4repair_space>hosts." ) ) ; break ; } else { DomainGroupVersion updatingToVersion = ring . getUpdatingToVersion ( ) ; if ( Rings . isUpToDate ( ring , updatingToVersion ) ) { RingGroupUpdateTransitionFunctionImpl . LOG . info ( ( ( "Ring<seq2seq4repair_space>" + ( ring . getRingNumber ( ) ) ) + "<seq2seq4repair_space>is<seq2seq4repair_space>UPDATED." ) ) ; ring . setState ( UPDATED ) ; } else { RingGroupUpdateTransitionFunctionImpl . LOG . info ( ( ( "No<seq2seq4repair_space>host<seq2seq4repair_space>in<seq2seq4repair_space>ring<seq2seq4repair_space>" + ( ring . getRingNumber ( ) ) ) + "<seq2seq4repair_space>was<seq2seq4repair_space>UPDATING<seq2seq4repair_space>but<seq2seq4repair_space>the<seq2seq4repair_space>ring<seq2seq4repair_space>is<seq2seq4repair_space>not<seq2seq4repair_space>up<seq2seq4repair_space>to<seq2seq4repair_space>date." ) ) ; for ( Host host : ring . getHosts ( ) ) { if ( ! ( Hosts . isUpToDate ( host , updatingToVersion ) ) ) { RingGroupUpdateTransitionFunctionImpl . LOG . info ( ( ( "Host<seq2seq4repair_space>" + host ) + "<seq2seq4repair_space>needs<seq2seq4repair_space>to<seq2seq4repair_space>UPDATE<seq2seq4repair_space>again<seq2seq4repair_space>since<seq2seq4repair_space>it<seq2seq4repair_space>is<seq2seq4repair_space>not<seq2seq4repair_space>up<seq2seq4repair_space>to<seq2seq4repair_space>date." ) ) ; if ( ! ( host . getCommandQueue ( ) . contains ( EXECUTE_UPDATE ) ) ) { host . enqueueCommand ( EXECUTE_UPDATE ) ; } } } break ; } } case UPDATED : anyDownOrUpdating = true ; RingGroupUpdateTransitionFunctionImpl . LOG . info ( ( ( "Ring<seq2seq4repair_space>" + ( ring . getRingNumber ( ) ) ) + "<seq2seq4repair_space>is<seq2seq4repair_space>fully<seq2seq4repair_space>updated.<seq2seq4repair_space>Commanding<seq2seq4repair_space>hosts<seq2seq4repair_space>to<seq2seq4repair_space>start<seq2seq4repair_space>up." ) ) ; ring . updateComplete ( ) ; Rings . commandAll ( ring , SERVE_DATA ) ; ring . setState ( COMING_UP ) ; break ; case COMING_UP : anyDownOrUpdating = true ; int numHostsServing = Rings . getHostsInState ( ring , SERVING ) . size ( ) ; if ( numHostsServing == ( ring . getHosts ( ) . size ( ) ) ) { RingGroupUpdateTransitionFunctionImpl . LOG . info ( ( ( "Ring<seq2seq4repair_space>" + ( ring . getRingNumber ( ) ) ) + "<seq2seq4repair_space>is<seq2seq4repair_space>fully<seq2seq4repair_space>online." ) ) ; ring . setState ( UP ) ; } else { RingGroupUpdateTransitionFunctionImpl . LOG . info ( ( ( "Ring<seq2seq4repair_space>" + ( ring . getRingNumber ( ) ) ) + "<seq2seq4repair_space>still<seq2seq4repair_space>has<seq2seq4repair_space>hosts<seq2seq4repair_space>that<seq2seq4repair_space>are<seq2seq4repair_space>not<seq2seq4repair_space>SERVING.<seq2seq4repair_space>Waiting<seq2seq4repair_space>for<seq2seq4repair_space>them<seq2seq4repair_space>to<seq2seq4repair_space>come<seq2seq4repair_space>up:" ) ) ; for ( Host host : ring . getHosts ( ) ) { RingGroupUpdateTransitionFunctionImpl . LOG . info ( String . format ( "<seq2seq4repair_space>[%s]<seq2seq4repair_space>%s" , host . getState ( ) , host ) ) ; } } break ; } } else { RingGroupUpdateTransitionFunctionImpl . LOG . info ( ( ( "Ring<seq2seq4repair_space>" + ( ring . getRingNumber ( ) ) ) + "<seq2seq4repair_space>is<seq2seq4repair_space>not<seq2seq4repair_space>in<seq2seq4repair_space>the<seq2seq4repair_space>process<seq2seq4repair_space>of<seq2seq4repair_space>updating." ) ) ; } } if ( ( ! anyDownOrUpdating ) && ( ! ( downable . isEmpty ( ) ) ) ) { Ring toDown = downable . poll ( ) ; RingGroupUpdateTransitionFunctionImpl . LOG . info ( ( ( ( ( "There<seq2seq4repair_space>were<seq2seq4repair_space>" + ( downable . size ( ) ) ) + "<seq2seq4repair_space>candidates<seq2seq4repair_space>for<seq2seq4repair_space>the<seq2seq4repair_space>next<seq2seq4repair_space>ring<seq2seq4repair_space>to<seq2seq4repair_space>update.<seq2seq4repair_space>Selecting<seq2seq4repair_space>ring<seq2seq4repair_space>" ) + ( toDown . getRingNumber ( ) ) ) + "." ) ) ; Rings . commandAll ( toDown , GO_TO_IDLE ) ; toDown . setState ( GOING_DOWN ) ; } if ( ! anyUpdatesPending ) { RingGroupUpdateTransitionFunctionImpl . LOG . info ( "There<seq2seq4repair_space>are<seq2seq4repair_space>no<seq2seq4repair_space>more<seq2seq4repair_space>updates<seq2seq4repair_space>pending.<seq2seq4repair_space>The<seq2seq4repair_space>update<seq2seq4repair_space>is<seq2seq4repair_space>complete!" ) ; ringGroup . updateComplete ( ) ; } } }

Fix:
if ( ( Rings . isUpdatePending ( ring ) ) || ( ( ring . getState ( ) ) != ( RingState . UP ) ) ) {