// Path: src/main/java/com/bazoud/elasticsearch/river/git/beans/Context.java
// @Data
// @SuppressWarnings("PMD.UnusedPrivateField")
// public class Context {
//     private String name;
//     private String uri;
//     private File projectPath;
//     private Repository repository;
//     private String workingDir =
//         System.getProperty("user.home") + File.separator + ".elasticsearch-river-git";
//     private Collection<Ref> refs;
//     private Client client;
//     private Optional<Pattern> issuePattern = Optional.absent();
//     private String issueRegex;
//     private boolean indexingDiff;
//     private long updateRate = TimeUnit.MILLISECONDS.convert(15, TimeUnit.MINUTES);
//     private String type = "git";
//     private String riverName;
//     private String riverIndexName;
// }
// 
// Path: src/main/java/com/bazoud/elasticsearch/river/git/beans/Identity.java
// @Data
// @Builder
// @SuppressWarnings("PMD.UnusedPrivateField")
// public class Identity {
//     private String name;
//     private String emailAddress;
//     private Date when;
//     private TimeZone timeZone;
//     private int timeZoneOffset;
// }
// 
// Path: src/main/java/com/bazoud/elasticsearch/river/git/beans/IndexCommit.java
// @Data
// @Builder
// @SuppressWarnings("PMD.UnusedPrivateField")
// public class IndexCommit implements Id {
//     private String id;
//     private String sha1;
//     private String project;
//     private Identity author;
//     private Identity committer;
//     private String subject;
//     private String messsage;
//     private String encoding;
//     private List<String> issues = new ArrayList<String>();
//     private List<Parent> parents = new ArrayList<Parent>();
//     private String diff;
// }
// 
// Path: src/main/java/com/bazoud/elasticsearch/river/git/beans/Parent.java
// @Data
// @Builder
// @SuppressWarnings("PMD.UnusedPrivateField")
// public class Parent {
//     private String id;
// }
// 
// Path: src/main/java/com/bazoud/elasticsearch/river/git/guava/MyFunction.java
// public abstract class MyFunction<F, T> implements Function<F, T> {
//     private static ESLogger logger = Loggers.getLogger(MyFunction.class);
// 
//     @Override
//     public T apply(F input) {
//         T output = null;
//         try {
//             output = doApply(input);
//         } catch (Throwable e) {
//             logger.error(this.getClass().getName(), e);
//             Throwables.propagate(e);
//         }
//         return output;
//     }
// 
//     public abstract T doApply(F input) throws Throwable;
// }


import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.diff.RawTextComparator;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import com.bazoud.elasticsearch.river.git.beans.Context;
import com.bazoud.elasticsearch.river.git.beans.Identity;
import com.bazoud.elasticsearch.river.git.beans.IndexCommit;
import com.bazoud.elasticsearch.river.git.beans.Parent;
import com.bazoud.elasticsearch.river.git.guava.MyFunction;
import com.google.common.base.Function;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Ordering;
import static com.bazoud.elasticsearch.river.git.IndexedDocumentType.COMMIT;
                    .from(Arrays.asList(revCommit.getParents()))
                    .transform(new Function<RevCommit, Parent>() {
                        @Override
                        public Parent apply(RevCommit commit) {
                            try {
                                return Parent.parent()
                                    .id(commit.getId().getName())
                                    .build();
                            } catch (Throwable e) {
                                logger.error(this.getClass().getName(), e);
                                return null;
                            }
                        }
                    })
                    .toList()
            )
            .diff(parseDiff(context, walk, revCommit))
            .build();
    }

    private String parseDiff(Context context, RevWalk walk, RevCommit revCommit) throws Exception {
        if (context.isIndexingDiff() && revCommit.getParentCount() > 0) {
            RevCommit parentCommit = walk.parseCommit(revCommit.getParent(0).getId());
            ByteArrayOutputStream diffOutputStream = new ByteArrayOutputStream();
            DiffFormatter diffFormatter = new DiffFormatter(diffOutputStream);
            diffFormatter.setRepository(context.getRepository());
            diffFormatter.setDiffComparator(RawTextComparator.DEFAULT);
            diffFormatter.setDetectRenames(true);
            diffFormatter.format(parentCommit.getTree(), revCommit.getTree());
            return new String(diffOutputStream.toByteArray());
// Path: src/main/java/com/bazoud/elasticsearch/river/git/beans/Context.java
// @Data
// @SuppressWarnings("PMD.UnusedPrivateField")
// public class Context {
//     private String name;
//     private String uri;
//     private File projectPath;
//     private Repository repository;
//     private String workingDir =
//         System.getProperty("user.home") + File.separator + ".elasticsearch-river-git";
//     private Collection<Ref> refs;
//     private Client client;
//     private Optional<Pattern> issuePattern = Optional.absent();
//     private String issueRegex;
//     private boolean indexingDiff;
//     private long updateRate = TimeUnit.MILLISECONDS.convert(15, TimeUnit.MINUTES);
//     private String type = "git";
//     private String riverName;
//     private String riverIndexName;
// }
// 
// Path: src/main/java/com/bazoud/elasticsearch/river/git/beans/Identity.java
// @Data
// @Builder
// @SuppressWarnings("PMD.UnusedPrivateField")
// public class Identity {
//     private String name;
//     private String emailAddress;
//     private Date when;
//     private TimeZone timeZone;
//     private int timeZoneOffset;
// }
// 
// Path: src/main/java/com/bazoud/elasticsearch/river/git/beans/IndexCommit.java
// @Data
// @Builder
// @SuppressWarnings("PMD.UnusedPrivateField")
// public class IndexCommit implements Id {
//     private String id;
//     private String sha1;
//     private String project;
//     private Identity author;
//     private Identity committer;
//     private String subject;
//     private String messsage;
//     private String encoding;
//     private List<String> issues = new ArrayList<String>();
//     private List<Parent> parents = new ArrayList<Parent>();
//     private String diff;
// }
// 
// Path: src/main/java/com/bazoud/elasticsearch/river/git/beans/Parent.java
// @Data
// @Builder
// @SuppressWarnings("PMD.UnusedPrivateField")
// public class Parent {
//     private String id;
// }
// 
// Path: src/main/java/com/bazoud/elasticsearch/river/git/guava/MyFunction.java
// public abstract class MyFunction<F, T> implements Function<F, T> {
//     private static ESLogger logger = Loggers.getLogger(MyFunction.class);
// 
//     @Override
//     public T apply(F input) {
//         T output = null;
//         try {
//             output = doApply(input);
//         } catch (Throwable e) {
//             logger.error(this.getClass().getName(), e);
//             Throwables.propagate(e);
//         }
//         return output;
//     }
// 
//     public abstract T doApply(F input) throws Throwable;
// }


// Path: src/main/java/com/bazoud/elasticsearch/river/git/flow/functions/RevCommitToIndexCommit.java
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.diff.RawTextComparator;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import com.bazoud.elasticsearch.river.git.beans.Context;
import com.bazoud.elasticsearch.river.git.beans.Identity;
import com.bazoud.elasticsearch.river.git.beans.IndexCommit;
import com.bazoud.elasticsearch.river.git.beans.Parent;
import com.bazoud.elasticsearch.river.git.guava.MyFunction;
import com.google.common.base.Function;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Ordering;
import static com.bazoud.elasticsearch.river.git.IndexedDocumentType.COMMIT;

                    .from(Arrays.asList(revCommit.getParents()))
                    .transform(new Function<RevCommit, Parent>() {
                        @Override
                        public Parent apply(RevCommit commit) {
                            try {
                                return Parent.parent()
                                    .id(commit.getId().getName())
                                    .build();
                            } catch (Throwable e) {
                                logger.error(this.getClass().getName(), e);
                                return null;
                            }
                        }
                    })
                    .toList()
            )
            .diff(parseDiff(context, walk, revCommit))
            .build();
    }

    private String parseDiff(Context context, RevWalk walk, RevCommit revCommit) throws Exception {
        if (context.isIndexingDiff() && revCommit.getParentCount() > 0) {
            RevCommit parentCommit = walk.parseCommit(revCommit.getParent(0).getId());
            ByteArrayOutputStream diffOutputStream = new ByteArrayOutputStream();
            DiffFormatter diffFormatter = new DiffFormatter(diffOutputStream);
            diffFormatter.setRepository(context.getRepository());
            diffFormatter.setDiffComparator(RawTextComparator.DEFAULT);
            diffFormatter.setDetectRenames(true);
            diffFormatter.format(parentCommit.getTree(), revCommit.getTree());
            return new String(diffOutputStream.toByteArray());
        } else {