code: @SuppressWarnings("unchecked")
      public static <T> T[] removeEmptySpans(T[] spans, Spanned spanned, Class<T> klass) {
          T[] copy = null;
          int count = 0;
  
          for (int i = 0; i < spans.length; i++) {
              final T span = spans[i];
              final int start = spanned.getSpanStart(span);
              final int end = spanned.getSpanEnd(span);
  
              if (start == end) {
                  if (copy == null) {
                      copy = (T[]) Array.newInstance(klass, spans.length - 1);
                      System.arraycopy(spans, 0, copy, 0, i);
                      count = i;
                  }
              } else {
                  if (copy != null) {
                      copy[count] = span;
                      count++;
                  }
              }
          }
  
          if (copy != null) {
              T[] result = (T[]) Array.newInstance(klass, count);
              System.arraycopy(copy, 0, result, 0, count);
              return result;
          } else {
              return spans;
          }
      }
docs: Removes empty spans from the <code>spans</code> array.
  
  When parsing a Spanned using {@link Spanned#nextSpanTransition(int, int, Class)}, empty spans
  will (correctly) create span transitions, and calling getSpans on a slice of text bounded by
  one of these transitions will (correctly) include the empty overlapping span.
  
  However, these empty spans should not be taken into account when layouting or rendering the
  string and this method provides a way to filter getSpans' results accordingly.
  
  @param spans A list of spans retrieved using {@link Spanned#getSpans(int, int, Class)} from
  the <code>spanned</code>
  @param spanned The Spanned from which spans were extracted
  @return A subset of spans where empty spans ({@link Spanned#getSpanStart(Object)}  ==
  {@link Spanned#getSpanEnd(Object)} have been removed. The initial order is preserved
  @hide