public MetaData getMetaData(int index) {
    if (indexMap == null || indexMap.length < index + 1) {
      int startFrom = 0;
      int lastIndex = index;

      if (indexMap != null) {
        startFrom = indexMap.length;
        indexMap = Arrays.copyOf(indexMap, index + 1);
      } else {
        String[] headers = context.headers();
        if (headers != null && lastIndex < headers.length) {
          lastIndex = headers.length;
        }

        int[] indexes = context.extractedFieldIndexes();
        if (indexes != null) {
          for (int i = 0; i < indexes.length; i++) {
            if (lastIndex < indexes[i]) {
              lastIndex = indexes[i];
            }
          }
        }

        indexMap = new MetaData[lastIndex + 1];
      }

      for (int i = startFrom; i < lastIndex + 1; i++) {
        indexMap[i] = new MetaData(i);
      }
    }
    return indexMap[index];
  }
 private MetaData getMetaData(Enum<?> column) {
   String[] headers = context.headers();
   if (headers == null || headers.length == 0) {
     throw new IllegalStateException(
         "No headers parsed from input nor provided in the user settings. Only index-based operations are available.");
   }
   return getMetaData(context.indexOf(column));
 }
 @Override
 public boolean containsColumn(String headerName) {
   if (headerName == null) {
     return false;
   }
   return context.indexOf(headerName) != -1;
 }
 private String[] getValidatedHeaders() {
   String[] headers = context.headers();
   if (headers == null || headers.length == 0) {
     throw new IllegalStateException(
         "No headers parsed from input nor provided in the user settings. Only index-based operations are available.");
   }
   return headers;
 }
 private MetaData getMetaData(String name) {
   int index = context.indexOf(name);
   if (index == -1) {
     getValidatedHeaders();
     throw new IllegalArgumentException(
         "Header name '"
             + name
             + "' not found. Available columns are: "
             + Arrays.asList(headers()));
   }
   return getMetaData(index);
 }
  @SuppressWarnings({"rawtypes", "unchecked"})
  private <T> T convert(
      MetaData md, String[] data, Class<T> type, T defaultValue, Annotation annotation) {
    Object out = data[md.index];

    if (out == null) {
      out = defaultValue == null ? md.defaultValue : defaultValue;
    }

    if (annotation == null) {
      initializeMetadataConversions(data, md);
      out = md.convert(out);

      if (out == null) {
        out = defaultValue == null ? md.defaultValue : defaultValue;
      }
    }

    if (type != null) {
      if (out != null && type.isAssignableFrom(out.getClass())) {
        return (T) out;
      }
      Conversion conversion;
      if (type != String.class) {
        if (annotation == null) {
          conversion = conversionByType.get(type);
          if (conversion == null) {
            conversion = AnnotationHelper.getDefaultConversion(type, null);
            conversionByType.put(type, conversion);
          }
        } else {
          Map<Annotation, Conversion> m = conversionsByAnnotation.get(type);
          if (m == null) {
            m = new HashMap<Annotation, Conversion>();
            conversionsByAnnotation.put(type, m);
          }
          conversion = m.get(annotation);
          if (conversion == null) {
            conversion = AnnotationHelper.getConversion(type, annotation);
            m.put(annotation, conversion);
          }
        }

        if (conversion == null) {
          String message = "";
          if (type == Date.class || type == Calendar.class) {
            message = ". Need to specify format for date";
          }
          DataProcessingException exception =
              new DataProcessingException(
                  "Cannot convert '{value}' to " + type.getName() + message);
          exception.setValue(out);
          exception.setErrorContentLength(context.errorContentLength());
          throw exception;
        }
        out = conversion.execute(out);
      }
    }
    if (type == null) {
      return (T) out;
    }
    try {
      return type.cast(out);
    } catch (ClassCastException e) {
      DataProcessingException exception =
          new DataProcessingException(
              "Cannot cast value '{value}' of type "
                  + out.getClass().toString()
                  + " to "
                  + type.getName());
      exception.setValue(out);
      exception.setErrorContentLength(context.errorContentLength());
      throw exception;
    }
  }
 @Override
 public String[] selectedHeaders() {
   return context.selectedHeaders();
 }
 @Override
 public String[] headers() {
   return context.headers();
 }