public static <C extends Comparable<?>>List<Range<C>> remove(Range<C> self,Range<C> other){
  if (other == null || !self.isConnected(other)) {
    return Collections.singletonList(self);
  }
  Range<C> share=self.intersection(other);
  if (share.isEmpty()) {
    return Collections.singletonList(self);
  }
  List<Range<C>> ret=Lists.newArrayList();
  if (!self.hasLowerBound()) {
    if (share.hasLowerBound()) {
      if (share.lowerBoundType() == BoundType.CLOSED) {
        ret.add(Range.lessThan(share.lowerEndpoint()));
      }
 else {
        ret.add(Range.atMost(share.lowerEndpoint()));
      }
    }
  }
 else {
    if (self.lowerEndpoint() != share.lowerEndpoint()) {
      if (self.lowerBoundType() == BoundType.CLOSED) {
        if (share.lowerBoundType() == BoundType.CLOSED) {
          ret.add(Range.closedOpen(self.lowerEndpoint(),share.lowerEndpoint()));
        }
 else {
          ret.add(Range.closed(self.lowerEndpoint(),share.lowerEndpoint()));
        }
      }
 else {
        if (share.lowerBoundType() == BoundType.CLOSED) {
          ret.add(Range.open(self.lowerEndpoint(),share.lowerEndpoint()));
        }
 else {
          ret.add(Range.openClosed(self.lowerEndpoint(),share.lowerEndpoint()));
        }
      }
    }
 else {
      if (self.lowerBoundType() == BoundType.CLOSED && share.lowerBoundType() == BoundType.OPEN) {
        ret.add(Range.closed(self.lowerEndpoint(),share.lowerEndpoint()));
      }
    }
  }
  if (!self.hasUpperBound()) {
    if (share.hasUpperBound()) {
      if (share.upperBoundType() == BoundType.CLOSED) {
        ret.add(Range.greaterThan(share.upperEndpoint()));
      }
 else {
        ret.add(Range.atLeast(share.upperEndpoint()));
      }
    }
  }
 else {
    if (self.upperEndpoint() != share.upperEndpoint()) {
      if (self.upperBoundType() == BoundType.CLOSED) {
        if (share.upperBoundType() == BoundType.CLOSED) {
          ret.add(Range.openClosed(share.upperEndpoint(),self.upperEndpoint()));
        }
 else {
          ret.add(Range.closed(share.upperEndpoint(),self.upperEndpoint()));
        }
      }
 else {
        if (share.upperBoundType() == BoundType.CLOSED) {
          ret.add(Range.open(share.upperEndpoint(),self.upperEndpoint()));
        }
 else {
          ret.add(Range.closedOpen(share.upperEndpoint(),self.upperEndpoint()));
        }
      }
    }
 else {
      if (self.upperBoundType() == BoundType.CLOSED && share.upperBoundType() == BoundType.OPEN) {
        ret.add(Range.closed(self.upperEndpoint(),share.upperEndpoint()));
      }
    }
  }
  return ret;
}

public static < C extends Comparable < ? > > List < Range < C > > remove ( Range < C > self , Range < C > other ) { if ( other == null || ! self . isConnected ( other ) ) { return Collections . singletonList ( self ) ; } Range < C > share = self . intersection ( other ) ; if ( share . isEmpty ( ) ) { return Collections . singletonList ( self ) ; } List < Range < C > > ret = Lists . newArrayList ( ) ; if ( ! self . hasLowerBound ( ) ) { if ( share . hasLowerBound ( ) ) { if ( share . lowerBoundType ( ) == BoundType . CLOSED ) { ret . add ( Range . lessThan ( share . lowerEndpoint ( ) ) ) ; } else { ret . add ( Range . atMost ( share . lowerEndpoint ( ) ) ) ; } } } else { if ( self . lowerEndpoint ( ) != share . lowerEndpoint ( ) ) { if ( self . lowerBoundType ( ) == BoundType . CLOSED ) { if ( share . lowerBoundType ( ) == BoundType . CLOSED ) { ret . add ( Range . closedOpen ( self . lowerEndpoint ( ) , share . lowerEndpoint ( ) ) ) ; } else { ret . add ( Range . closed ( self . lowerEndpoint ( ) , share . lowerEndpoint ( ) ) ) ; } } else { if ( share . lowerBoundType ( ) == BoundType . CLOSED ) { ret . add ( Range . open ( self . lowerEndpoint ( ) , share . lowerEndpoint ( ) ) ) ; } else { ret . add ( Range . openClosed ( self . lowerEndpoint ( ) , share . lowerEndpoint ( ) ) ) ; } } } else { if ( self . lowerBoundType ( ) == BoundType . CLOSED && share . lowerBoundType ( ) == BoundType . OPEN ) { ret . add ( Range . closed ( self . lowerEndpoint ( ) , share . lowerEndpoint ( ) ) ) ; } } } if ( ! self . hasUpperBound ( ) ) { if ( share . hasUpperBound ( ) ) { if ( share . upperBoundType ( ) == BoundType . CLOSED ) { ret . add ( Range . greaterThan ( share . upperEndpoint ( ) ) ) ; } else { ret . add ( Range . atLeast ( share . upperEndpoint ( ) ) ) ; } } } else { if ( self . upperEndpoint ( ) != share . upperEndpoint ( ) ) { if ( self . upperBoundType ( ) == BoundType . CLOSED ) { if ( share . upperBoundType ( ) == BoundType . CLOSED ) { ret . add ( Range . openClosed ( share . upperEndpoint ( ) , self . upperEndpoint ( ) ) ) ; } else { ret . add ( Range . closed ( share . upperEndpoint ( ) , self . upperEndpoint ( ) ) ) ; } } else { if ( share . upperBoundType ( ) == BoundType . CLOSED ) { ret . add ( Range . open ( share . upperEndpoint ( ) , self . upperEndpoint ( ) ) ) ; } else { ret . add ( Range . closedOpen ( share . upperEndpoint ( ) , self . upperEndpoint ( ) ) ) ; } } } else { if ( self . upperBoundType ( ) == BoundType . CLOSED && share . upperBoundType ( ) == BoundType . OPEN ) { ret . add ( Range . closed ( self . upperEndpoint ( ) , share . upperEndpoint ( ) ) ) ; } } } return ret ; }
remove from self the elements that exist in other
