docs: public static DataWriter getWriter(OutputStream out, CategoricalData[] catInfo, int dim, final CategoricalData predicting, final FloatStorageMethod fpStore, DataWriter.DataSetType type) throws IOException
      {
          return new DataWriter(out, catInfo, dim, type)
          {
              @Override
              protected void writeHeader(CategoricalData[] catInfo, int dim, DataWriter.DataSetType type, OutputStream out) throws IOException
              {
                  DataOutputStream data_out = new DataOutputStream(out);
          
                  data_out.write(JSATData.MAGIC_NUMBER);
  
                  int numNumeric = dim;
                  int numCat = catInfo.length;
  
                  DatasetTypeMarker marker = DatasetTypeMarker.STANDARD;
                  if(type == type.REGRESSION)
                  {
                      numNumeric++;
                      marker = DatasetTypeMarker.REGRESSION;
                  }
                  if(type == type.CLASSIFICATION)
                  {
                      numCat++;
                      marker = DatasetTypeMarker.CLASSIFICATION;
                  }
  
                  data_out.writeByte(marker.ordinal());
                  data_out.writeByte(fpStore.ordinal());
                  data_out.writeInt(numNumeric);
                  data_out.writeInt(numCat);
                  data_out.writeInt(-1);//-1 used to indicate a potentially variable number of files
  
                  for(CategoricalData category : catInfo)
                  {
                      //first, whats the name of the i'th category
                      writeString(category.getCategoryName(), data_out);
  
                      data_out.writeInt(category.getNumOfCategories());//output the number of categories 
                      for(int i = 0; i < category.getNumOfCategories(); i++)//the option names
                          writeString(category.getOptionName(i), data_out);
                  }
                  //extra for classification dataset
                  if(type == DataWriter.DataSetType.CLASSIFICATION)
                  {
                      CategoricalData category = predicting;
                      //first, whats the name of the i'th category
                      writeString(category.getCategoryName(), data_out);
  
                      data_out.writeInt(category.getNumOfCategories());//output the number of categories 
                      for(int i = 0; i < category.getNumOfCategories(); i++)//the option names
                          writeString(category.getOptionName(i), data_out);
                  }
                  data_out.flush();
              }
              
              @Override
              protected void pointToBytes(double weight, DataPoint dp, double label, ByteArrayOutputStream byteOut)
              {
                  try
                  {
                      DataOutputStream data_out = new DataOutputStream(byteOut);
                      fpStore.writeFP(weight, data_out);
                      for(int val : dp.getCategoricalValues())
                          data_out.writeInt(val);
                      if(type == DataWriter.DataSetType.CLASSIFICATION)
                          data_out.writeInt((int) label);
                      
                      Vec numericVals = dp.getNumericalValues();
                      
                      data_out.writeBoolean(numericVals.isSparse());
                      if(numericVals.isSparse())
                      {
                          if(type == DataWriter.DataSetType.REGRESSION)
                              data_out.writeInt(numericVals.nnz()+1);//+1 for the target value, which may actually be zero...
                          else
                              data_out.writeInt(numericVals.nnz());
                          
                          for(IndexValue iv : numericVals)
                          {
                              data_out.writeInt(iv.getIndex());
                              fpStore.writeFP(iv.getValue(), data_out);
                          }
                      }
                      else
                      {
                          for(int j = 0; j < numericVals.length(); j++)
                              fpStore.writeFP(numericVals.get(j), data_out);
                      }
                      
                      //append the target value
                      if(type == DataWriter.DataSetType.REGRESSION)
                      {
                          /*
                          * if dense, we only need to just add the extra double. If
                          * sparse, we do the index and then the double.
                          */
                          if (numericVals.isSparse())
                              data_out.writeInt(numericVals.length());
                          
                          fpStore.writeFP(label, data_out);
                      }
                      data_out.flush();
                  }
                  catch (IOException ex)
                  {
                      Logger.getLogger(JSATData.class.getName()).log(Level.SEVERE, null, ex);
                  }
              }
          };
      }