final Resources result = Resources.empty();

package io.github.lonamiwebs.stringlate.classes.sources;

import net.gsantner.opoc.util.FileUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.github.lonamiwebs.stringlate.classes.Messenger;
import io.github.lonamiwebs.stringlate.classes.git.GitCloneProgressCallback;
import io.github.lonamiwebs.stringlate.classes.git.GitWrapper;
import io.github.lonamiwebs.stringlate.classes.resources.Resources;
import io.github.lonamiwebs.stringlate.classes.resources.tags.ResTag;
import io.github.lonamiwebs.stringlate.interfaces.StringsSource;

public class GitSource implements StringsSource {

    private File mWorkDir;

    private final String mGitUrl, mBranch;

    private final HashMap<String, ArrayList<File>> mLocaleFiles;

    private GitCloneProgressCallback mCloneCallback;

    private boolean mCancelled;

    private File iconFile;

    // Match locale from "values-(…)/strings.xml"
    private final static Pattern VALUES_LOCALE_PATTERN = Pattern.compile("values(?:-([\\w-]+))?/.+?\\.xml");

    private static final Pattern DO_NOT_TRANSLATE = Pattern.compile("(?:do?[ _-]*no?t?|[u|i]n)[ _-]*trans(?:lat(?:e|able))?");

    public GitSource(final String gitUrl, final String branch) {
        mGitUrl = gitUrl;
        mBranch = branch;
        mLocaleFiles = new HashMap<>();
    }

    @Override
    public boolean setup(final SourceSettings settings, final File workDir, final int desiredIconDpi, final Messenger.OnSyncProgress callback) {
        callback.onUpdate(1, 0f);
        settings.set("git_url", mGitUrl);
        mWorkDir = workDir;
        // 2. Clone the repository itself
        mCloneCallback = new GitCloneProgressCallback(callback);
        if (!GitWrapper.cloneRepo(mGitUrl, mWorkDir, mBranch, mCloneCallback) || mCancelled) {
            // TODO These messages are still useful, show them somehow?
            return false;
        }
        // Cache all the repository resources here for faster look-up on upcoming methods
        final GitWrapper.RepositoryResources repoResources = GitWrapper.findUsefulResources(mWorkDir);
        final ArrayList<File> resourceFiles = GitWrapper.searchAndroidResources(repoResources);
        if (resourceFiles.isEmpty() || mCancelled) {
            return false;
        }
        // Save the branches of this repository
        settings.setArray("remote_branches", GitWrapper.getBranches(mWorkDir));
        iconFile = GitWrapper.findProperIcon(repoResources, desiredIconDpi);
        // Iterate over all the found resources to sort them by locale
        for (File resourceFile : resourceFiles) {
            Matcher m = VALUES_LOCALE_PATTERN.matcher(resourceFile.getAbsolutePath());
            // Ensure that we can tell the locale from the path (otherwise it's invalid)
            if (m.find()) {
                if (m.group(1) == null) {
                    // Default locale
                    // If the file name is something like "do not translate", skip it
                    if (DO_NOT_TRANSLATE.matcher(resourceFile.getName()).find())
                        continue;
                }
                // TODO Can I use .getOrDefault()? It shows an error so let's not risk
                if (!mLocaleFiles.containsKey(m.group(1)))
                    mLocaleFiles.put(m.group(1), new ArrayList<File>());
                mLocaleFiles.get(m.group(1)).add(resourceFile);
            }
        }
        settings.set("translation_service", GitWrapper.mayUseTranslationServices(repoResources));
        return !mCancelled;
    }

    @Override
    public void cancel() {
        if (mCloneCallback != null) {
            mCloneCallback.cancel();
        }
        mCancelled = true;
    }

    @Override
    public String getName() {
        return "git";
    }

    @Override
    public List<String> getLocales() {
        final ArrayList<String> result = new ArrayList<>(mLocaleFiles.size());
        for (String locale : mLocaleFiles.keySet()) if (locale != null)
            result.add(locale);
        return result;
    }

    @Override
    public Resources getResources(final String locale) {

        for (File file : mLocaleFiles.get(locale)) {
            for (ResTag rt : Resources.fromFile(file)) result.addTag(rt);
        }
        return result;
    }

    @Override
    public List<String> getDefaultResources() {
        final ArrayList<String> result = new ArrayList<>(mLocaleFiles.get(null).size());
        for (File file : mLocaleFiles.get(null)) result.add(getDefaultResourceName(file));
        return result;
    }

    @Override
    public Resources getDefaultResource(String name) {
        for (File file : mLocaleFiles.get(null)) if (getDefaultResourceName(file).equals(name))
            return Resources.fromFile(file);
        throw new IllegalArgumentException("No default resources were found with that name");
    }

    @Override
    public String getDefaultResourceXml(String name) {
        for (File file : mLocaleFiles.get(null)) if (getDefaultResourceName(file).equals(name))
            return FileUtils.readTextFile(file);
        throw new IllegalArgumentException("No XML was found with that name");
    }

    @Override
    public File getIcon() {
        return iconFile;
    }

    private String getDefaultResourceName(final File file) {
        return file.getAbsolutePath().substring(mWorkDir.getAbsolutePath().length() + 1);
    }

    @Override
    public void dispose() {
        FileUtils.deleteRecursive(mWorkDir);
        mLocaleFiles.clear();
        iconFile = null;
    }
}


for (File file : mLocaleFiles.get(locale)) {
            for (ResTag rt : Resources.fromFile(file)) result.addTag(rt);
        }

package io.github.lonamiwebs.stringlate.classes.sources;

import net.gsantner.opoc.util.FileUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.github.lonamiwebs.stringlate.classes.Messenger;
import io.github.lonamiwebs.stringlate.classes.git.GitCloneProgressCallback;
import io.github.lonamiwebs.stringlate.classes.git.GitWrapper;
import io.github.lonamiwebs.stringlate.classes.resources.Resources;
import io.github.lonamiwebs.stringlate.classes.resources.tags.ResTag;
import io.github.lonamiwebs.stringlate.interfaces.StringsSource;

public class GitSource implements StringsSource {

    private File mWorkDir;

    private final String mGitUrl, mBranch;

    private final HashMap<String, ArrayList<File>> mLocaleFiles;

    private GitCloneProgressCallback mCloneCallback;

    private boolean mCancelled;

    private File iconFile;

    // Match locale from "values-(…)/strings.xml"
    private final static Pattern VALUES_LOCALE_PATTERN = Pattern.compile("values(?:-([\\w-]+))?/.+?\\.xml");

    private static final Pattern DO_NOT_TRANSLATE = Pattern.compile("(?:do?[ _-]*no?t?|[u|i]n)[ _-]*trans(?:lat(?:e|able))?");

    public GitSource(final String gitUrl, final String branch) {
        mGitUrl = gitUrl;
        mBranch = branch;
        mLocaleFiles = new HashMap<>();
    }

    @Override
    public boolean setup(final SourceSettings settings, final File workDir, final int desiredIconDpi, final Messenger.OnSyncProgress callback) {
        callback.onUpdate(1, 0f);
        settings.set("git_url", mGitUrl);
        mWorkDir = workDir;
        // 2. Clone the repository itself
        mCloneCallback = new GitCloneProgressCallback(callback);
        if (!GitWrapper.cloneRepo(mGitUrl, mWorkDir, mBranch, mCloneCallback) || mCancelled) {
            // TODO These messages are still useful, show them somehow?
            return false;
        }
        // Cache all the repository resources here for faster look-up on upcoming methods
        final GitWrapper.RepositoryResources repoResources = GitWrapper.findUsefulResources(mWorkDir);
        final ArrayList<File> resourceFiles = GitWrapper.searchAndroidResources(repoResources);
        if (resourceFiles.isEmpty() || mCancelled) {
            return false;
        }
        // Save the branches of this repository
        settings.setArray("remote_branches", GitWrapper.getBranches(mWorkDir));
        iconFile = GitWrapper.findProperIcon(repoResources, desiredIconDpi);
        // Iterate over all the found resources to sort them by locale
        for (File resourceFile : resourceFiles) {
            Matcher m = VALUES_LOCALE_PATTERN.matcher(resourceFile.getAbsolutePath());
            // Ensure that we can tell the locale from the path (otherwise it's invalid)
            if (m.find()) {
                if (m.group(1) == null) {
                    // Default locale
                    // If the file name is something like "do not translate", skip it
                    if (DO_NOT_TRANSLATE.matcher(resourceFile.getName()).find())
                        continue;
                }
                // TODO Can I use .getOrDefault()? It shows an error so let's not risk
                if (!mLocaleFiles.containsKey(m.group(1)))
                    mLocaleFiles.put(m.group(1), new ArrayList<File>());
                mLocaleFiles.get(m.group(1)).add(resourceFile);
            }
        }
        settings.set("translation_service", GitWrapper.mayUseTranslationServices(repoResources));
        return !mCancelled;
    }

    @Override
    public void cancel() {
        if (mCloneCallback != null) {
            mCloneCallback.cancel();
        }
        mCancelled = true;
    }

    @Override
    public String getName() {
        return "git";
    }

    @Override
    public List<String> getLocales() {
        final ArrayList<String> result = new ArrayList<>(mLocaleFiles.size());
        for (String locale : mLocaleFiles.keySet()) if (locale != null)
            result.add(locale);
        return result;
    }

    @Override
    public Resources getResources(final String locale) {
        final Resources result = Resources.empty();

        return result;
    }

    @Override
    public List<String> getDefaultResources() {
        final ArrayList<String> result = new ArrayList<>(mLocaleFiles.get(null).size());
        for (File file : mLocaleFiles.get(null)) result.add(getDefaultResourceName(file));
        return result;
    }

    @Override
    public Resources getDefaultResource(String name) {
        for (File file : mLocaleFiles.get(null)) if (getDefaultResourceName(file).equals(name))
            return Resources.fromFile(file);
        throw new IllegalArgumentException("No default resources were found with that name");
    }

    @Override
    public String getDefaultResourceXml(String name) {
        for (File file : mLocaleFiles.get(null)) if (getDefaultResourceName(file).equals(name))
            return FileUtils.readTextFile(file);
        throw new IllegalArgumentException("No XML was found with that name");
    }

    @Override
    public File getIcon() {
        return iconFile;
    }

    private String getDefaultResourceName(final File file) {
        return file.getAbsolutePath().substring(mWorkDir.getAbsolutePath().length() + 1);
    }

    @Override
    public void dispose() {
        FileUtils.deleteRecursive(mWorkDir);
        mLocaleFiles.clear();
        iconFile = null;
    }
}


package io.github.lonamiwebs.stringlate.classes.sources;

import net.gsantner.opoc.util.FileUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.github.lonamiwebs.stringlate.classes.Messenger;
import io.github.lonamiwebs.stringlate.classes.git.GitCloneProgressCallback;
import io.github.lonamiwebs.stringlate.classes.git.GitWrapper;
import io.github.lonamiwebs.stringlate.classes.resources.Resources;
import io.github.lonamiwebs.stringlate.classes.resources.tags.ResTag;
import io.github.lonamiwebs.stringlate.interfaces.StringsSource;

public class GitSource implements StringsSource {

    private File mWorkDir;

    private final String mGitUrl, mBranch;

    private final HashMap<String, ArrayList<File>> mLocaleFiles;

    private GitCloneProgressCallback mCloneCallback;

    private boolean mCancelled;

    private File iconFile;

    // Match locale from "values-(…)/strings.xml"
    private final static Pattern VALUES_LOCALE_PATTERN = Pattern.compile("values(?:-([\\w-]+))?/.+?\\.xml");

    private static final Pattern DO_NOT_TRANSLATE = Pattern.compile("(?:do?[ _-]*no?t?|[u|i]n)[ _-]*trans(?:lat(?:e|able))?");

    public GitSource(final String gitUrl, final String branch) {
        mGitUrl = gitUrl;
        mBranch = branch;
        mLocaleFiles = new HashMap<>();
    }

    @Override
    public boolean setup(final SourceSettings settings, final File workDir, final int desiredIconDpi, final Messenger.OnSyncProgress callback) {
        callback.onUpdate(1, 0f);
        settings.set("git_url", mGitUrl);
        mWorkDir = workDir;
        // 2. Clone the repository itself
        mCloneCallback = new GitCloneProgressCallback(callback);
        if (!GitWrapper.cloneRepo(mGitUrl, mWorkDir, mBranch, mCloneCallback) || mCancelled) {
            // TODO These messages are still useful, show them somehow?
            return false;
        }
        // Cache all the repository resources here for faster look-up on upcoming methods
        final GitWrapper.RepositoryResources repoResources = GitWrapper.findUsefulResources(mWorkDir);
        final ArrayList<File> resourceFiles = GitWrapper.searchAndroidResources(repoResources);
        if (resourceFiles.isEmpty() || mCancelled) {
            return false;
        }
        // Save the branches of this repository
        settings.setArray("remote_branches", GitWrapper.getBranches(mWorkDir));
        iconFile = GitWrapper.findProperIcon(repoResources, desiredIconDpi);
        // Iterate over all the found resources to sort them by locale
        for (File resourceFile : resourceFiles) {
            Matcher m = VALUES_LOCALE_PATTERN.matcher(resourceFile.getAbsolutePath());
            // Ensure that we can tell the locale from the path (otherwise it's invalid)
            if (m.find()) {
                if (m.group(1) == null) {
                    // Default locale
                    // If the file name is something like "do not translate", skip it
                    if (DO_NOT_TRANSLATE.matcher(resourceFile.getName()).find())
                        continue;
                }
                // TODO Can I use .getOrDefault()? It shows an error so let's not risk
                if (!mLocaleFiles.containsKey(m.group(1)))
                    mLocaleFiles.put(m.group(1), new ArrayList<File>());
                mLocaleFiles.get(m.group(1)).add(resourceFile);
            }
        }
        settings.set("translation_service", GitWrapper.mayUseTranslationServices(repoResources));
        return !mCancelled;
    }

    @Override
    public void cancel() {
        if (mCloneCallback != null) {
            mCloneCallback.cancel();
        }
        mCancelled = true;
    }

    @Override
    public String getName() {
        return "git";
    }

    @Override
    public List<String> getLocales() {
        final ArrayList<String> result = new ArrayList<>(mLocaleFiles.size());
        for (String locale : mLocaleFiles.keySet()) if (locale != null)
            result.add(locale);
        return result;
    }

    @Override
    public Resources getResources(final String locale) {
        final Resources result = Resources.empty();
        for (File file : mLocaleFiles.get(locale)) {
            for (ResTag rt : Resources.fromFile(file)) result.addTag(rt);
        }

    @Override
    public List<String> getDefaultResources() {
        final ArrayList<String> result = new ArrayList<>(mLocaleFiles.get(null).size());
        for (File file : mLocaleFiles.get(null)) result.add(getDefaultResourceName(file));
        return result;
    }

    @Override
    public Resources getDefaultResource(String name) {
        for (File file : mLocaleFiles.get(null)) if (getDefaultResourceName(file).equals(name))
            return Resources.fromFile(file);
        throw new IllegalArgumentException("No default resources were found with that name");
    }

    @Override
    public String getDefaultResourceXml(String name) {
        for (File file : mLocaleFiles.get(null)) if (getDefaultResourceName(file).equals(name))
            return FileUtils.readTextFile(file);
        throw new IllegalArgumentException("No XML was found with that name");
    }

    @Override
    public File getIcon() {
        return iconFile;
    }

    private String getDefaultResourceName(final File file) {
        return file.getAbsolutePath().substring(mWorkDir.getAbsolutePath().length() + 1);
    }

    @Override
    public void dispose() {
        FileUtils.deleteRecursive(mWorkDir);
        mLocaleFiles.clear();
        iconFile = null;
    }
}


package io.github.lonamiwebs.stringlate.classes.sources;

import net.gsantner.opoc.util.FileUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.github.lonamiwebs.stringlate.classes.Messenger;
import io.github.lonamiwebs.stringlate.classes.git.GitCloneProgressCallback;
import io.github.lonamiwebs.stringlate.classes.git.GitWrapper;
import io.github.lonamiwebs.stringlate.classes.resources.Resources;
import io.github.lonamiwebs.stringlate.classes.resources.tags.ResTag;
import io.github.lonamiwebs.stringlate.interfaces.StringsSource;

public class GitSource implements StringsSource {

    private File mWorkDir;

    private final String mGitUrl, mBranch;

    private final HashMap<String, ArrayList<File>> mLocaleFiles;

    private GitCloneProgressCallback mCloneCallback;

    private boolean mCancelled;

    private File iconFile;

    // Match locale from "values-(…)/strings.xml"
    private final static Pattern VALUES_LOCALE_PATTERN = Pattern.compile("values(?:-([\\w-]+))?/.+?\\.xml");

    private static final Pattern DO_NOT_TRANSLATE = Pattern.compile("(?:do?[ _-]*no?t?|[u|i]n)[ _-]*trans(?:lat(?:e|able))?");

    public GitSource(final String gitUrl, final String branch) {
        mGitUrl = gitUrl;
        mBranch = branch;
        mLocaleFiles = new HashMap<>();
    }

    @Override
    public boolean setup(final SourceSettings settings, final File workDir, final int desiredIconDpi, final Messenger.OnSyncProgress callback) {
        callback.onUpdate(1, 0f);
        settings.set("git_url", mGitUrl);
        mWorkDir = workDir;
        // 2. Clone the repository itself
        mCloneCallback = new GitCloneProgressCallback(callback);
        if (!GitWrapper.cloneRepo(mGitUrl, mWorkDir, mBranch, mCloneCallback) || mCancelled) {
            // TODO These messages are still useful, show them somehow?
            return false;
        }
        // Cache all the repository resources here for faster look-up on upcoming methods
        final GitWrapper.RepositoryResources repoResources = GitWrapper.findUsefulResources(mWorkDir);
        final ArrayList<File> resourceFiles = GitWrapper.searchAndroidResources(repoResources);
        if (resourceFiles.isEmpty() || mCancelled) {
            return false;
        }
        // Save the branches of this repository
        settings.setArray("remote_branches", GitWrapper.getBranches(mWorkDir));
        iconFile = GitWrapper.findProperIcon(repoResources, desiredIconDpi);
        // Iterate over all the found resources to sort them by locale
        for (File resourceFile : resourceFiles) {
            Matcher m = VALUES_LOCALE_PATTERN.matcher(resourceFile.getAbsolutePath());
            // Ensure that we can tell the locale from the path (otherwise it's invalid)
            if (m.find()) {
                if (m.group(1) == null) {
                    // Default locale
                    // If the file name is something like "do not translate", skip it
                    if (DO_NOT_TRANSLATE.matcher(resourceFile.getName()).find())
                        continue;
                }
                // TODO Can I use .getOrDefault()? It shows an error so let's not risk
                if (!mLocaleFiles.containsKey(m.group(1)))
                    mLocaleFiles.put(m.group(1), new ArrayList<File>());
                mLocaleFiles.get(m.group(1)).add(resourceFile);
            }
        }
        settings.set("translation_service", GitWrapper.mayUseTranslationServices(repoResources));
        return !mCancelled;
    }

    @Override
    public void cancel() {
        if (mCloneCallback != null) {
            mCloneCallback.cancel();
        }
        mCancelled = true;
    }

    @Override
    public String getName() {
        return "git";
    }

    @Override
    public List<String> getLocales() {
        final ArrayList<String> result = new ArrayList<>(mLocaleFiles.size());
        for (String locale : mLocaleFiles.keySet()) if (locale != null)
            result.add(locale);
        return result;
    }

    @Override
    public Resources getResources(final String locale) {
        final Resources result = Resources.empty();
        for (File file : mLocaleFiles.get(locale)) {
            for (ResTag rt : Resources.fromFile(file)) result.addTag(rt);
        }
        return result;
    }

    @Override
    public List<String> getDefaultResources() {
        final ArrayList<String> result = new ArrayList<>(mLocaleFiles.get(null).size());
        for (File file : mLocaleFiles.get(null)) result.add(getDefaultResourceName(file));
        return result;
    }

    @Override
    public Resources getDefaultResource(String name) {
        for (File file : mLocaleFiles.get(null)) if (getDefaultResourceName(file).equals(name))
            return Resources.fromFile(file);
        throw new IllegalArgumentException("No default resources were found with

    }

    @Override
    public String getDefaultResourceXml(String name) {
        for (File file : mLocaleFiles.get(null)) if (getDefaultResourceName(file).equals(name))
            return FileUtils.readTextFile(file);
        throw new IllegalArgumentException("No XML was found with that name");
    }

    @Override
    public File getIcon() {
        return iconFile;
    }

    private String getDefaultResourceName(final File file) {
        return file.getAbsolutePath().substring(mWorkDir.getAbsolutePath().length() + 1);
    }

    @Override
    public void dispose() {
        FileUtils.deleteRecursive(mWorkDir);
        mLocaleFiles.clear();
        iconFile = null;
    }
}


if (getDefaultResourceName(file).equals(name))
            return Resources.fromFile(file);

package io.github.lonamiwebs.stringlate.classes.sources;

import net.gsantner.opoc.util.FileUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.github.lonamiwebs.stringlate.classes.Messenger;
import io.github.lonamiwebs.stringlate.classes.git.GitCloneProgressCallback;
import io.github.lonamiwebs.stringlate.classes.git.GitWrapper;
import io.github.lonamiwebs.stringlate.classes.resources.Resources;
import io.github.lonamiwebs.stringlate.classes.resources.tags.ResTag;
import io.github.lonamiwebs.stringlate.interfaces.StringsSource;

public class GitSource implements StringsSource {

    private File mWorkDir;

    private final String mGitUrl, mBranch;

    private final HashMap<String, ArrayList<File>> mLocaleFiles;

    private GitCloneProgressCallback mCloneCallback;

    private boolean mCancelled;

    private File iconFile;

    // Match locale from "values-(…)/strings.xml"
    private final static Pattern VALUES_LOCALE_PATTERN = Pattern.compile("values(?:-([\\w-]+))?/.+?\\.xml");

    private static final Pattern DO_NOT_TRANSLATE = Pattern.compile("(?:do?[ _-]*no?t?|[u|i]n)[ _-]*trans(?:lat(?:e|able))?");

    public GitSource(final String gitUrl, final String branch) {
        mGitUrl = gitUrl;
        mBranch = branch;
        mLocaleFiles = new HashMap<>();
    }

    @Override
    public boolean setup(final SourceSettings settings, final File workDir, final int desiredIconDpi, final Messenger.OnSyncProgress callback) {
        callback.onUpdate(1, 0f);
        settings.set("git_url", mGitUrl);
        mWorkDir = workDir;
        // 2. Clone the repository itself
        mCloneCallback = new GitCloneProgressCallback(callback);
        if (!GitWrapper.cloneRepo(mGitUrl, mWorkDir, mBranch, mCloneCallback) || mCancelled) {
            // TODO These messages are still useful, show them somehow?
            return false;
        }
        // Cache all the repository resources here for faster look-up on upcoming methods
        final GitWrapper.RepositoryResources repoResources = GitWrapper.findUsefulResources(mWorkDir);
        final ArrayList<File> resourceFiles = GitWrapper.searchAndroidResources(repoResources);
        if (resourceFiles.isEmpty() || mCancelled) {
            return false;
        }
        // Save the branches of this repository
        settings.setArray("remote_branches", GitWrapper.getBranches(mWorkDir));
        iconFile = GitWrapper.findProperIcon(repoResources, desiredIconDpi);
        // Iterate over all the found resources to sort them by locale
        for (File resourceFile : resourceFiles) {
            Matcher m = VALUES_LOCALE_PATTERN.matcher(resourceFile.getAbsolutePath());
            // Ensure that we can tell the locale from the path (otherwise it's invalid)
            if (m.find()) {
                if (m.group(1) == null) {
                    // Default locale
                    // If the file name is something like "do not translate", skip it
                    if (DO_NOT_TRANSLATE.matcher(resourceFile.getName()).find())
                        continue;
                }
                // TODO Can I use .getOrDefault()? It shows an error so let's not risk
                if (!mLocaleFiles.containsKey(m.group(1)))
                    mLocaleFiles.put(m.group(1), new ArrayList<File>());
                mLocaleFiles.get(m.group(1)).add(resourceFile);
            }
        }
        settings.set("translation_service", GitWrapper.mayUseTranslationServices(repoResources));
        return !mCancelled;
    }

    @Override
    public void cancel() {
        if (mCloneCallback != null) {
            mCloneCallback.cancel();
        }
        mCancelled = true;
    }

    @Override
    public String getName() {
        return "git";
    }

    @Override
    public List<String> getLocales() {
        final ArrayList<String> result = new ArrayList<>(mLocaleFiles.size());
        for (String locale : mLocaleFiles.keySet()) if (locale != null)
            result.add(locale);
        return result;
    }

    @Override
    public Resources getResources(final String locale) {
        final Resources result = Resources.empty();
        for (File file : mLocaleFiles.get(locale)) {
            for (ResTag rt : Resources.fromFile(file)) result.addTag(rt);
        }
        return result;
    }

    @Override
    public List<String> getDefaultResources() {
        final ArrayList<String> result = new ArrayList<>(mLocaleFiles.get(null).size());
        for (File file : mLocaleFiles.get(null)) result.add(getDefaultResourceName(file));
        return result;
    }

    @Override
    public Resources getDefaultResource(String name) {
        for (File file : mLocaleFiles.get(null))

        throw new IllegalArgumentException("No default resources were found with that name");
    }

    @Override
    public String getDefaultResourceXml(String name) {
        for (File file : mLocaleFiles.get(null)) if (getDefaultResourceName(file).equals(name))
            return FileUtils.readTextFile(file);
        throw new IllegalArgumentException("No XML was found with that name");
    }

    @Override
    public File getIcon() {
        return iconFile;
    }

    private String getDefaultResourceName(final File file) {
        return file.getAbsolutePath().substring(mWorkDir.getAbsolutePath().length() + 1);
    }

    @Override
    public void dispose() {
        FileUtils.deleteRecursive(mWorkDir);
        mLocaleFiles.clear();
        iconFile = null;
    }
}


package io.github.lonamiwebs.stringlate.classes.sources;

import net.gsantner.opoc.util.FileUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.github.lonamiwebs.stringlate.classes.Messenger;
import io.github.lonamiwebs.stringlate.classes.git.GitCloneProgressCallback;
import io.github.lonamiwebs.stringlate.classes.git.GitWrapper;
import io.github.lonamiwebs.stringlate.classes.resources.Resources;
import io.github.lonamiwebs.stringlate.classes.resources.tags.ResTag;
import io.github.lonamiwebs.stringlate.interfaces.StringsSource;

public class GitSource implements StringsSource {

    private File mWorkDir;

    private final String mGitUrl, mBranch;

    private final HashMap<String, ArrayList<File>> mLocaleFiles;

    private GitCloneProgressCallback mCloneCallback;

    private boolean mCancelled;

    private File iconFile;

    // Match locale from "values-(…)/strings.xml"
    private final static Pattern VALUES_LOCALE_PATTERN = Pattern.compile("values(?:-([\\w-]+))?/.+?\\.xml");

    private static final Pattern DO_NOT_TRANSLATE = Pattern.compile("(?:do?[ _-]*no?t?|[u|i]n)[ _-]*trans(?:lat(?:e|able))?");

    public GitSource(final String gitUrl, final String branch) {
        mGitUrl = gitUrl;
        mBranch = branch;
        mLocaleFiles = new HashMap<>();
    }

    @Override
    public boolean setup(final SourceSettings settings, final File workDir, final int desiredIconDpi, final Messenger.OnSyncProgress callback) {
        callback.onUpdate(1, 0f);
        settings.set("git_url", mGitUrl);
        mWorkDir = workDir;
        // 2. Clone the repository itself
        mCloneCallback = new GitCloneProgressCallback(callback);
        if (!GitWrapper.cloneRepo(mGitUrl, mWorkDir, mBranch, mCloneCallback) || mCancelled) {
            // TODO These messages are still useful, show them somehow?
            return false;
        }
        // Cache all the repository resources here for faster look-up on upcoming methods
        final GitWrapper.RepositoryResources repoResources = GitWrapper.findUsefulResources(mWorkDir);
        final ArrayList<File> resourceFiles = GitWrapper.searchAndroidResources(repoResources);
        if (resourceFiles.isEmpty() || mCancelled) {
            return false;
        }
        // Save the branches of this repository
        settings.setArray("remote_branches", GitWrapper.getBranches(mWorkDir));
        iconFile = GitWrapper.findProperIcon(repoResources, desiredIconDpi);
        // Iterate over all the found resources to sort them by locale
        for (File resourceFile : resourceFiles) {
            Matcher m = VALUES_LOCALE_PATTERN.matcher(resourceFile.getAbsolutePath());
            // Ensure that we can tell the locale from the path (otherwise it's invalid)
            if (m.find()) {
                if (m.group(1) == null) {
                    // Default locale
                    // If the file name is something like "do not translate", skip it
                    if (DO_NOT_TRANSLATE.matcher(resourceFile.getName()).find())
                        continue;
                }
                // TODO Can I use .getOrDefault()? It shows an error so let's not risk
                if (!mLocaleFiles.containsKey(m.group(1)))
                    mLocaleFiles.put(m.group(1), new ArrayList<File>());
                mLocaleFiles.get(m.group(1)).add(resourceFile);
            }
        }
        settings.set("translation_service", GitWrapper.mayUseTranslationServices(repoResources));
        return !mCancelled;
    }

    @Override
    public void cance

l() {
        if (mCloneCallback != null) {
            mCloneCallback.cancel();
        }
        mCancelled = true;
    }

    @Override
    public String getName() {
        return "git";
    }

    @Override
    public List<String> getLocales() {
        final ArrayList<String> result = new ArrayList<>(mLocaleFiles.size());
        for (String locale : mLocaleFiles.keySet()) if (locale != null)
            result.add(locale);
        return result;
    }

    @Override
    public Resources getResources(final String locale) {
        final Resources result = Resources.empty();
        for (File file : mLocaleFiles.get(locale)) {
            for (ResTag rt : Resources.fromFile(file)) result.addTag(rt);
        }
        return result;
    }

    @Override
    public List<String> getDefaultResources() {
        final ArrayList<String> result = new ArrayList<>(mLocaleFiles.get(null).size());
        for (File file : mLocaleFiles.get(null)) result.add(getDefaultResourceName(file));
        return result;
    }

    @Override
    public Resources getDefaultResource(String name) {
        for (File file : mLocaleFiles.get(null)) if (getDefaultResourceName(file).equals(name))
            return Resources.fromFile(file);
        throw new IllegalArgumentException("No default resources were found with that name");
    }

    @Override
    public String getDefaultResourceXml(String name) {
        for (File file : mLocaleFiles.get(null)) if (getDefaultResourceName(file).equals(name))
            return FileUtils.readTextFile(file);
        throw new IllegalArgumentException("No XML was found with that name");
    }

    @Override
    public File getIcon() {
        return iconFile;
    }

    private String getDefaultResourceName(final File file) {
        return file.getAbsolutePath().substring(mWorkDir.getAbsolutePath().length() + 1);
    }

    @Override
    public void dispose() {
        FileUtils.deleteRecursive(mWorkDir);
        mLocaleFiles.clear();
        iconFile = null;
    }
}


package org.glassfish.jersey.tests.integration.servlet_25_inflector_1;

import org.glassfish.jersey.server.ResourceConfig;
import org.gl

assfish.jersey.server.model.Resource;

/**
 * @author Michal Gajdos
 */
public class MyApplication extends ResourceConfig {

    public MyApplication() {
        final Resource.Builder resourceBuilder = Resource.builder("resource");
        resourceBuilder.addChildResource("class").addMethod("GET").handledBy(MyInflector.class);
        resourceBuilder.addChildResource("instance").addMethod("GET").handledBy(new MyInflector());
        registerResources(resourceBuilder.build());
    }
}


package org.apache.ignite.internal.processors.cache.persistence.wal;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.apache.ignite.internal.util.GridUnsafe;

/**
 * ByteBuffer wrapper for dynamically expand buffer size.
 */
public class ByteBufferExpander implements AutoCloseable {

    /**
     * Byte buffer
     */
    private ByteBuffer buf;

    /**
     * @param initSize Initial size.
     * @param order Byte order.
     */
    public ByteBufferExpander(int initSize, ByteOrder order) {
        ByteBuffer buffer = GridUnsafe.allocateBuffer(initSize);
        buffer.order(order);
        buf = buffer;
    }

{
        return buf;
    }

    /**
     * Expands current byte buffer to the requested size.
     *
     * @return ByteBuffer with requested size.
     */
    public ByteBuffer expand(int size) {
        assert buf.capacity() < size;
        int pos = buf.position();
        int lim = buf.limit();
        ByteBuffer newBuf = GridUnsafe.reallocateBuffer(buf, size);
        newBuf.order(buf.order());
        newBuf.position(pos);
        newBuf.limit(lim);
        buf = newBuf;
        return newBuf;
    }

    @Override
    public void close() {
        GridUnsafe.freeBuffer(buf);
    }
}


package org.apache.ignite.internal.processors.cache.persistence.wal;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.apache.ignite.internal.util.GridUnsafe;

/**
 * ByteBuffer wrapper for dynamically expand buffer size.
 */
public class ByteBufferExpander implements AutoCloseable {

    /**
     * Byte buffer
     */
    private ByteBuffer buf;

    /**
     * @param initSize Initial size.
     * @param order Byte order.
     */
    public ByteBufferExpander(int initSize, ByteOrder order) {
        ByteBuffer buffer = GridUnsafe.allocateBuffer(initSize);
        buffer.order(order);
        buf = buffer;
    }

    public ByteBuffer buffer()

    /**
     * Expands current byte buffer to the requested size.
     *
     * @return ByteBuffer with requested size.
     */
    public ByteBuffer expand(int size) {
        assert buf.capacity() < size;
        int pos = buf.position();
        int lim = buf.limit();
        ByteBuffer newBuf = GridUnsafe.reallocateBuffer(buf, size);
        newBuf.order(buf.order());
        newBuf.position(pos);
        newBuf.limit(lim);
        buf = newBuf;
        return newBuf;
    }

    @Override
    public void close() {
        GridUnsafe.freeBuffer(buf);
    }
}


        assert buf.capacity() < size;
        int pos = buf.position();
        int lim = buf.limit();

package org.apache.ignite.internal.processors.cache.persistence.wal;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.apache.ignite.internal.util.GridUnsafe;

/**
 * ByteBuffer wrapper for dynamically expand buffer size.
 */
public class ByteBufferExpander implements AutoCloseable {

    /**
     * Byte buffer
     */
    private ByteBuffer buf;

    /**
     * @param initSize Initial size.
     * @param order Byte order.
     */
    public ByteBufferExpander(int initSize, ByteOrder order) {
        ByteBuffer buffer = GridUnsafe.allocateBuffer(initSize);
        buffer.order(order);
        buf = buffer;
    }

    public ByteBuffer buffer() {
        return buf;
    }

    /**
     * Expands current byte buffer to the requested size.
     *
     * @return ByteBuffer with requested size.
     */
    public ByteBuffer expand(int size) {

        ByteBuffer newBuf = GridUnsafe.reallocateBuffer(buf, size);
        newBuf.order(buf.order());
        newBuf.position(pos);
        newBuf.limit(lim);
        buf = newBuf;
        return newBuf;
    }

    @Override
    public void close() {
        GridUnsafe.freeBuffer(buf);
    }
}


ByteBuffer newBuf = GridUnsafe.reallocateBuffer(buf, size);
        newBuf.order(buf.order());
        newBuf.position(pos);

package org.apache.ignite.internal.processors.cache.persistence.wal;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.apache.ignite.internal.util.GridUnsafe;

/**
 * ByteBuffer wrapper for dynamically expand buffer size.
 */
public class ByteBufferExpander implements AutoCloseable {

    /**
     * Byte buffer
     */
    private ByteBuffer buf;

    /**
     * @param initSize Initial size.
     * @param order Byte order.
     */
    public ByteBufferExpander(int initSize, ByteOrder order) {
        ByteBuffer buffer = GridUnsafe.allocateBuffer(initSize);
        buffer.order(order);
        buf = buffer;
    }

    public ByteBuffer buffer() {
        return buf;
    }

    /**
     * Expands current byte buffer to the requested size.
     *
     * @return ByteBuffer with requested size.
     */
    public ByteBuffer expand(int size) {
        assert buf.capacity() < size;
        int pos = buf.position();
        int lim = buf.limit();

        newBuf.limit(lim);
        buf = newBuf;
        return newBuf;
    }

    @Override
    public void close() {
        GridUnsafe.freeBuffer(buf);
    }
}


newBuf.limit(lim);
        buf = newBuf;
        return newBuf;
    }

package org.apache.ignite.internal.processors.cache.persistence.wal;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.apache.ignite.internal.util.GridUnsafe;

/**
 * ByteBuffer wrapper for dynamically expand buffer size.
 */
public class ByteBufferExpander implements AutoCloseable {

    /**
     * Byte buffer
     */
    private ByteBuffer buf;

    /**
     * @param initSize Initial size.
     * @param order Byte order.
     */
    public ByteBufferExpander(int initSize, ByteOrder order) {
        ByteBuffer buffer = GridUnsafe.allocateBuffer(initSize);
        buffer.order(order);
        buf = buffer;
    }

    public ByteBuffer buffer() {
        return buf;
    }

    /**
     * Expands current byte buffer to the requested size.
     *
     * @return ByteBuffer with requested size.
     */
    public ByteBuffer expand(int size) {
        assert buf.capacity() < size;
        int pos = buf.position();
        int lim = buf.limit();
        ByteBuffer newBuf = GridUnsafe.reallocateBuffer(buf, size);
        newBuf.order(buf.order());
        newBuf.position(pos);

    @Override
    public void close() {
        GridUnsafe.freeBuffer(buf);
    }
}


package org.apache.ignite.internal.processors.cache.persistence.wal;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.apache.ignite.internal.util.GridUnsafe;

/**
 * ByteBuffer wrapper for dynamically expand buffer size.
 */
public class ByteBufferExpander implements AutoCloseable {

    /**
     * Byte buffer
     */
    private ByteBuffer buf;

    /**
     * @param initSize Initial size.
     * @param order Byte order.
     */
    public ByteBufferExpander(int initSize, ByteOrder order) {
        ByteBuffer buffer = GridUnsafe.allocateBuffer(initSize);
        buffer.order(order);
        buf = buffer;
    }

    public ByteBuffer buffer() {
        return buf;
    }

    /**
     * Expands current byte buffer to the requested size.
     *
     * @return ByteBuffer with requested size.
     */
    public ByteBuffer expand(int size) {
        assert buf

        int pos = buf.position();
        int lim = buf.limit();
        ByteBuffer newBuf = GridUnsafe.reallocateBuffer(buf, size);
        newBuf.order(buf.order());
        newBuf.position(pos);
        newBuf.limit(lim);
        buf = newBuf;
        return newBuf;
    }

    @Override
    public void close() {
        GridUnsafe.freeBuffer(buf);
    }
}


public ByteBuffer expand(int size) {
        assert buf.capacity() < size;
        int pos = buf.position();
        int lim = buf.limit();
        ByteBuffer newBuf = GridUnsafe.reallocateBuffer(buf, size);
        newBuf.order(buf.order());
        newBuf.position(pos);
        newBuf.limit(lim);
        buf = newBuf;
        return newBuf;
    }

package org.apache.ignite.internal.processors.cache.persistence.wal;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.apache.ignite.internal.util.GridUnsafe;

/**
 * ByteBuffer wrapper for dynamically expand buffer size.
 */
public class ByteBufferExpander implements AutoCloseable {

    /**
     * Byte buffer
     */
    private ByteBuffer buf;

    /**
     * @param initSize Initial size.
     * @param order Byte order.
     */
    public ByteBufferExpander(int initSize, ByteOrder order) {
        ByteBuffer buffer = GridUnsafe.allocateBuffer(initSize);
        buffer.order(order);
        buf = buffer;
    }

    public ByteBuffer buffer() {
        return buf;
    }

    /**
     * Expands current byte buffer to the requested size.
     *
     * @return ByteBuffer with requested size.
     */


tence.wal;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.apache.ignite.internal.util.GridUnsafe;

/**
 * ByteBuffer wrapper for dynamically expand buffer size.
 */
public class ByteBufferExpander implements AutoCloseable {

    /**
     * Byte buffer
     */
    private ByteBuffer buf;

    /**
     * @param initSize Initial size.
     * @param order Byte order.
     */
    public ByteBufferExpander(int initSize, ByteOrder order) {
        ByteBuffer buffer = GridUnsafe.allocateBuffer(initSize);
        buffer.order(order);
        buf = buffer;
    }

    public ByteBuffer buffer() {
        return buf;
    }

    /**
     * Expands current byte buffer to the requested size.
     *
     * @return ByteBuffer with requested size.
     */
    public ByteBuffer expand(int size) {
        assert buf.capacity() < size;
        int pos = buf.position();
        int lim = buf.limit();
        ByteBuffer newBuf = GridUnsafe.reallocateBuffer(buf, size);
        newBuf.order(buf.order());
        newBuf.position(pos);
        newBuf.limit(lim);
        buf = newBuf;
        return newBuf;
    }

    @Override
    public void close() {
        GridUnsafe.freeBuffer(buf);
    }
}


package org.packt.functional.codes.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;
import org.packt.functional.codes.model.data.Employee;
import org.springframework.stereotype.Service;

@Service("employeeDataService")
public class EmployeeDataService {

    public Employee createEmployee() {
        Supplier<Employee> newEmp = Employee::new;
        return newEmp.get();
    }

{
        Supplier<List<Employee>> newList = ArrayList::new;
        return newList.get();
    }

    public Date convertBday(long bdayLong) {
        Function<Long, Date> bday = Date::new;
        return bday.apply(bdayLong);
    }
}


{
        Function<Long, Date> bday = Date::new;
        return bday.apply(bdayLong);
    }

package org.packt.functional.codes.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;
import org.packt.functional.codes.model.data.Employee;
import org.springframework.stereotype.Service;

@Service("employeeDataService")
public class EmployeeDataService {

    public Employee createEmployee() {
        Supplier<Employee> newEmp = Employee::new;
        return newEmp.get();
    }

    public List<Employee> startList() {
        Supplier<List<Employee>> newList = ArrayList::new;
        return newList.get();
    }

    public Date convertBday(long bdayLong)


package org.packt.functional.codes.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;
import org.packt.functional.codes.model.data.Employee;
import org.springframework.stereotype.Service;

@Service("employeeDataService")
public class EmployeeDataService {

    public Employee createEmployee() {
        Supplier<Employee> newEmp = Employee::new;
        retur

    }

    public List<Employee> startList() {
        Supplier<List<Employee>> newList = ArrayList::new;
        return newList.get();
    }

    public Date convertBday(long bdayLong) {
        Function<Long, Date> bday = Date::new;
        return bday.apply(bdayLong);
    }
}


package org.packt.functional.codes.service.impl;

import java.util.ArrayList;

import java.util.Date;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;
import org.packt.functional.codes.model.data.Employee;
import org.springframework.stereotype.Service;

@Service("employeeDataService")
public class EmployeeDataService {

    public Employee createEmployee() {
        Supplier<Employee> newEmp = Employee::new;
        return newEmp.get();
    }

    public List<Employee> startList() {
        Supplier<List<Employee>> newList = ArrayList::new;
        return newList.get();
    }

    public Date convertBday(long bdayLong) {
        Function<Long, Date> bday = Date::new;
        return bday.apply(bdayLong);
    }
}


void afterUnmarshal(Unmarshaller u, Object parent)

/*
 * This file is part of aion-lightning <aion-lightning.org>
 *
 */
package com.aionemu.gameserver.dataholders;

import com.aionemu.gameserver.model.templates.assemblednpc.AssembledNpcTemplate;
import java.util.List;
import java.util.Map;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javolution.util.FastMap;

/**
 * @author xTz
 */
@XmlRootElement(name = "assembled_npcs")
@XmlAccessorType(XmlAccessType.FIELD)
public class AssembledNpcsData {

    @XmlElement(name = "assembled_npc", type = AssembledNpcTemplate.class)
    private List<AssembledNpcTemplate> templates;

    private final Map<Integer, AssembledNpcTemplate> assembledNpcsTemplates = new FastMap<Integer, AssembledNpcTemplate>().shared();

{
        for (AssembledNpcTemplate template : templates) {
            assembledNpcsTemplates.put(template.getNr(), template);
        }
        templates.clear();
        templates = null;
    }

    public int size() {
        return assembledNpcsTemplates.size();
    }

    public AssembledNpcTemplate getAssembledNpcTemplate(Integer i) {
        return assembledNpcsTemplates.get(i);
    }
}


{
        return assembledNpcsTemplates.size();
    }

/*
 * This file is part of aion-lightning <aion-lightning.org>
 *
 */
package com.aionemu.gameserver.dataholders;

import com.aionemu.gameserver.model.templates.assemblednpc.AssembledNpcTemplate;
import java.util.List;
import java.util.Map;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javolution.util.FastMap;

/**
 * @author xTz
 */
@XmlRootElement(name = "assembled_npcs")
@XmlAccessorType(XmlAccessType.FIELD)
public class AssembledNpcsData {

    @XmlElement(name = "assembled_npc", type = AssembledNpcTemplate.class)
    private List<AssembledNpcTemplate> templates;

    private final Map<Integer, AssembledNpcTemplate> assembledNpcsTemplates = new FastMap<Integer, AssembledNpcTemplate>().shared();

    void afterUnmarshal(Unmarshaller u, Object parent) {
        for (AssembledNpcTemplate template : templates) {
            assembledNpcsTemplates.put(template.getNr(), template);
        }
        templates.clear();
        templates = null;
    }

    public int size()

    public AssembledNpcTemplate getAssembledNpcTemplate(Integer i) {
        return assembledNpcsTemplates.get(i);
    }
}


        for (AssembledNpcTemplate template : templates) {
            assembledNpcsTemplates.put(template.getNr(), template);
        }

/*
 * This file is part of aion-lightning <aion-lightning.org>
 *
 */
package com.aionemu.gameserver.dataholders;

import com.aionemu.gameserver.model.templates.assemblednpc.AssembledNpcTemplate;
import java.util.List;
import java.util.Map;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javolution.util.FastMap;

/**
 * @author xTz
 */
@XmlRootElement(name = "assembled_npcs")
@XmlAccessorType(XmlAccessType.FIELD)
public class AssembledNpcsData {

    @XmlElement(name = "assembled_npc", type = AssembledNpcTemplate.class)
    private List<AssembledNpcTemplate> templates;

    private final Map<Integer, AssembledNpcTemplate> assembledNpcsTemplates = new FastMap<Integer, AssembledNpcTemplate>().shared();

    void afterUnmarshal(Unmarshaller u, Object parent) {

        templates.clear();
        templates = null;
    }

    public int size() {
        return assembledNpcsTemplates.size();
    }

    public AssembledNpcTemplate getAssembledNpcTemplate(Integer i) {
        return assembledNpcsTemplates.get(i);
    }
}


/*
 * This file is part of aion-lightning <aion-lightning.org>
 *
 */
package com.aionemu.gameserver.dataholders;

import com.aionemu.gameserver.model.templates.assemblednpc.AssembledNpcTemplate;
import java.util.List;
import java.util.Map;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javolution.util.FastMap;

/**
 * @author xTz
 */
@XmlRootElement(name = "assembled_npcs")
@XmlAccessorType(XmlAccessType.FIELD)
public class AssembledNpcsData {

    @XmlElement(name = "assembled_npc", type = AssembledNpcTemplate.class)
    private List<AssembledNpcTemplate> templates;

    private final Map<Integer, AssembledNpcTemplate> assembledNpcsTemplates = new FastMap<Integer, AssembledNpcTemplate>().shared();

    void afterUnmarshal(Unmarshaller u, Object parent) {
        for (AssembledNpcTemplate template : templates) {
            assembledNpcsTemplates.put(template.getNr(), template);
        }

        templates = null;
    }

    public int size() {
        return assembledNpcsTemplates.size();
    }

    public AssembledNpcTemplate getAssembledNpcTemplate(Integer i) {
        return assembledNpcsTemplates.get(i);
    }
}


/*
 * This file is part of aion-lightning <aion-lightning.org>
 *
 */
package com.aionemu.gameserver.dataholders;

import com.aionemu.gameserver.model.templates.assemblednpc.AssembledNpcTemplate;
import java.util.List;
import java.util.Map;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javolution.util.FastMap;

/**
 * @author xTz
 */
@XmlRootElement(name = "assembled_npcs")
@XmlAccessorType(XmlAccessType.FIELD)
public class AssembledNpcsData {

    @XmlElement(name = "assembled_npc", type = AssembledNpcTemplate.class)
    private List<AssembledNpcTemplate> templates;

    private final Map<Integer, AssembledNpcTemplate> assembledNpcsTemplates = new FastMap<Integer, AssembledNpcTemplate>().shared();

    void afterUnmarshal(Unmarshaller u, Object parent) {
        for (AssembledNpcTemplate template : templates) {
            assembledNpcsTemplates.put(template.getNr(), template);
        }
        templates.clear();

    public int size() {
        return assembledNpcsTemplates.size();
    }

    public AssembledNpcTemplate getAssembledNpcTemplate(Integer i) {
        return assembledNpcsTemplates.get(i);
    }
}


/*
 * This file is part of aion-lightning <aion-lightning.org>
 *
 */
package com.aionemu.gameserver.dataholders;

import com.aionemu.gameserver.model.templates.assemblednpc.AssembledNpcTemplate;
import java.util.List;
import java.util.Map;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javolution.util.FastMap;

/**
 * @author xTz
 */
@XmlRootElement(name = "assembled_npcs")
@XmlAccessorType(XmlAccessType.FIELD)
public class AssembledNpcsData {

    @XmlElement(name = "assembled_npc", type = AssembledNpcTemplate.class)
    private List<AssembledNpcTemplate> templates;

    private final Map<Integer, AssembledNpcTemplate> assembledNpcsTemplates = new FastMap<Integer, AssembledNpcTemplate>().shared();

    void afterUnmarshal(Unmarshaller u, Object parent) {
        for (AssembledNpcTemplate template : templates) {
            assembledNpcsTemplates.put(template.getNr(), template);
        }
        templates.clear(


/*
 * This file is part of aion-lightning <aion-lightning.org>
 *
 */
package com.aionemu.gameserver.dataholders;

import com.aionemu.gameserver.model.templates.assemblednpc.AssembledNpcTemplate;
import java.util.List;
import java.util.Map;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javolution.util.FastMap;

/**
 * @author xTz
 */
@XmlRootElement(name = "assembled_npcs")
@XmlAccessorType(XmlAccessType.FIELD)
public class AssembledNpcsData {

    @XmlElement(name = "assembled_npc", type = AssembledNpcTemplate.class)
    private List<AssembledNpcTemplate> templates;

    private final Map<Integer, AssembledNpcTemplate> assembledNpcsTemplates = new FastMap<Integer, AssembledNpcTemplate>().shared();

    void afterUnmarshal(Unmarshaller u, Object parent) {
        for (AssembledNpcTemplate template : templates) {
            assembledNpcsTemplates.put(template.getNr(), template);
        }
        templates.clear();
        templates = null;
    }

    public int size() {
        return assembledNpcsTemplates.size();
    }

    public Ass

embledNpcTemplate getAssembledNpcTemplate(Integer i) {
        return assembledNpcsTemplates.get(i);
    }
}


package org.eclipse.jetty.rewrite.handler;

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.pathmap.ServletPathSpec;

/**
 * Abstract rule that use a {@link ServletPathSpec} for pattern matching. It uses the
 * servlet pattern syntax.
 */
public abstract class PatternRule extends Rule {

    protected String _pattern;

    protected PatternRule() {
    }

    protected PatternRule(String pattern) {
        this();
        setPattern(pattern);
    }

{
        return _pattern;
    }

    /**
     * Sets the rule pattern.
     *
     * @param pattern the pattern
     */
    public void setPattern(String pattern) {
        _pattern = pattern;
    }

    @Override
    public String matchAndApply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException {
        if (ServletPathSpec.match(_pattern, target)) {
            return apply(target, request, response);
        }
        return null;
    }

    /**
     * Apply the rule to the request
     *
     * @param target field to attempt match
     * @param request request object
     * @param response response object
     * @return The target (possible updated)
     * @throws IOException exceptions dealing with operating on request or response objects
     */
    protected abstract String apply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException;

    /**
     * Returns the rule pattern.
     */
    @Override
    public String toString() {
        return super.toString() + "[" + _pattern + "]";
    }
}


{
        if (ServletPathSpec.match(_pattern, target)) {
            return apply(target, request, response);
        }
        return null;
    }

package org.eclipse.jetty.rewrite.handler;

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.pathmap.ServletPathSpec;

/**
 * Abstract rule that use a {@link ServletPathSpec} for pattern matching. It uses the
 * servlet pattern syntax.
 */
public abstract class PatternRule extends Rule {

    protected String _pattern;

    protected PatternRule() {
    }

    protected PatternRule(String pattern) {
        this();
        setPattern(pattern);
    }

    public String getPattern() {
        return _pattern;
    }

    /**
     * Sets the rule pattern.
     *
     * @param pattern the pattern
     */
    public void setPattern(String pattern) {
        _pattern = pattern;
    }

    @Override
    public String matchAndApply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException

    /**
     * Apply the rule to the request
     *
     * @param target field to attempt match
     * @param request request object
     * @param response response object
     * @return The target (possible updated)
     * @throws IOException exceptions dealing with operating on request or response objects
     */
    protected abstract String apply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException;

    /**
     * Returns the rule pattern.
     */
    @Override
    public String toString() {
        return super.toString() + "[" + _pattern + "]";
    }
}


package org.eclipse.jetty.rewrite.handler;

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.pathmap.ServletPathSpec;

/**
 * Abstract rule that use a {@link ServletPathSpec} for pattern matching. It uses the
 * servlet pattern syntax.
 */
public abstract class PatternRule extends Rule {

    protected String _pattern;

    protected PatternRule() {
    }

    protected PatternRule(String pattern) {
        this();
        setPattern(pattern);
    }

    public String getPattern() {
        return _pattern;
    }

    /**
     * Sets the rule pattern.
     *
     * @param pattern the pattern
     */
    public void setPattern(String pattern) {
        _pattern = pattern;
    }

    @Override
    public String matchAndApply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException {
        if (ServletPathSpec.match(_pattern, target)) {
            return apply(target, request, response);
        }
        r

    }

    /**
     * Apply the rule to the request
     *
     * @param target field to attempt match
     * @param request request object
     * @param response response object
     * @return The target (possible updated)
     * @throws IOException exceptions dealing with operating on request or response objects
     */
    protected abstract String apply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException;

    /**
     * Returns the rule pattern.
     */
    @Override
    public String toString() {
        return super.toString() + "[" + _pattern + "]";
    }
}


public void setPattern(String pattern) {
        _pattern = pattern;
    }

package org.eclipse.jetty.rewrite.handler;

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.pathmap.ServletPathSpec;

/**
 * Abstract rule that use a {@link ServletPathSpec} for pattern matching. It uses the
 * servlet pattern syntax.
 */
public abstract class PatternRule extends Rule {

    protected String _pattern;

    protected PatternRule() {
    }

    protected PatternRule(String pattern) {
        this();
        setPattern(pattern);
    }

    public String getPattern() {
        return _pattern;
    }

    /**
     * Sets the rule pattern.
     *
     * @param pattern the pattern
     */

    @Override
    public String matchAndApply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException {
        if (ServletPathSpec.match(_pattern, target)) {
            return apply(target, request, response);
        }
        return null;
    }

    /**
     * Apply the rule to the request
     *
     * @param target field to attempt match
     * @param request request object
     * @param response response object
     * @return The target (possible updated)
     * @throws IOException exceptions dealing with operating on request or response objects
     */
    protected abstract String apply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException;

    /**
     * Returns the rule pattern.
     */
    @Override
    public String toString() {
        return super.toString() + "[" + _pattern + "]";
    }
}


if (ServletPathSpec.match(_pattern, target)) {
            return apply(target, request, response);
        }

package org.eclipse.jetty.rewrite.handler;

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.pathmap.ServletPathSpec;

/**
 * Abstract rule that use a {@link ServletPathSpec} for pattern matching. It uses the
 * servlet pattern syntax.
 */
public abstract class PatternRule extends Rule {

    protected String _pattern;

    protected PatternRule() {
    }

    protected PatternRule(String pattern) {
        this();
        setPattern(pattern);
    }

    public String getPattern() {
        return _pattern;
    }

    /**
     * Sets the rule pattern.
     *
     * @param pattern the pattern
     */
    public void setPattern(String pattern) {
        _pattern = pattern;
    }

    @Override
    public String matchAndApply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException {

        return null;
    }

    /**
     * Apply the rule to the request
     *
     * @param target field to attempt match
     * @param request request object
     * @param response response object
     * @return The target (possible updated)
     * @throws IOException exceptions dealing with operating on request or response objects
     */
    protected abstract String apply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException;

    /**
     * Returns the rule pattern.
     */
    @Override
    public String toString() {
        return super.toString() + "[" + _pattern + "]";
    }
}


package org.eclipse.jetty.rewrite.handler;

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.pathmap.ServletPathSpec;

/**
 * Abstract rule that use a {@link ServletPathSpec} for pattern matching. It uses the
 * servlet pattern syntax.
 */
public abstract class PatternRule extends Rule {

    protected String _pattern;

    protected PatternRule() {
    }

    protected PatternRule(String pattern) {
        this();

setPattern(pattern);
    }

    public String getPattern() {
        return _pattern;
    }

    /**
     * Sets the rule pattern.
     *
     * @param pattern the pattern
     */
    public void setPattern(String pattern) {
        _pattern = pattern;
    }

    @Override
    public String matchAndApply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException {
        if (ServletPathSpec.match(_pattern, target)) {
            return apply(target, request, response);
        }
        return null;
    }

    /**
     * Apply the rule to the request
     *
     * @param target field to attempt match
     * @param request request object
     * @param response response object
     * @return The target (possible updated)
     * @throws IOException exceptions dealing with operating on request or response objects
     */
    protected abstract String apply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException;

    /**
     * Returns the rule pattern.
     */
    @Override
    public String toString() {
        return super.toString() + "[" + _pattern + "]";
    }
}


@SuppressLint("UseSparseArrays")
    private static void findCollidingIds(List<SubmissionRowUiModel> rows)

package me.saket.dank.ui.subreddit;

import android.annotation.SuppressLint;
import android.support.annotation.CheckResult;
import android.support.v7.util.DiffUtil;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import io.reactivex.Observable;
import io.reactivex.functions.Consumer;
import me.saket.dank.data.SwipeEvent;
import me.saket.dank.ui.subreddit.events.SubredditSubmissionClickEvent;
import me.saket.dank.ui.subreddit.events.SubredditSubmissionThumbnailClickEvent;
import me.saket.dank.ui.subreddit.uimodels.SubredditScreenUiModel;
import me.saket.dank.ui.subreddit.uimodels.SubredditScreenUiModel.SubmissionRowUiModel;
import me.saket.dank.ui.subreddit.uimodels.SubredditSubmission;
import me.saket.dank.ui.subreddit.uimodels.SubredditSubmissionPagination;
import me.saket.dank.utils.InfinitelyScrollableRecyclerViewAdapter;
import me.saket.dank.utils.Pair;
import me.saket.dank.utils.RecyclerViewArrayAdapter;
import me.saket.dank.walkthrough.SubmissionGestureWalkthroughProceedEvent;
import me.saket.dank.walkthrough.SubmissionGesturesWalkthrough;

public class SubredditSubmissionsAdapter extends RecyclerViewArrayAdapter<SubmissionRowUiModel, RecyclerView.ViewHolder> implements Consumer<Pair<List<SubmissionRowUiModel>, DiffUtil.DiffResult>>, InfinitelyScrollableRecyclerViewAdapter {

    public static final int ADAPTER_ID_PAGINATION_FOOTER = -99;

    public static final long ADAPTER_ID_GESTURES_WALKTHROUGH = -98;

    private static final SubmissionRowUiModel.Type[] VIEW_TYPES = SubmissionRowUiModel.Type.values();

    private final Map<SubmissionRowUiModel.Type, SubredditScreenUiModel.SubmissionRowUiChildAdapter> childAdapters;

    private final SubredditSubmission.Adapter submissionAdapter;

    private final SubredditSubmissionPagination.Adapter paginationAdapter;

    private final SubmissionGesturesWalkthrough.Adapter gestureWalkthroughAdapter;

    @Inject
    public SubredditSubmissionsAdapter(SubmissionGesturesWalkthrough.Adapter gestureWalkthroughAdapter, SubredditSubmission.Adapter submissionAdapter, SubredditSubmissionPagination.Adapter paginationAdapter) {
        childAdapters = new HashMap<>(4);
        childAdapters.put(SubmissionRowUiModel.Type.GESTURES_WALKTHROUGH, gestureWalkthroughAdapter);
        childAdapters.put(SubmissionRowUiModel.Type.SUBMISSION, submissionAdapter);
        childAdapters.put(SubmissionRowUiModel.Type.PAGINATION_FOOTER, paginationAdapter);
        this.gestureWalkthroughAdapter = gestureWalkthroughAdapter;
        this.paginationAdapter = paginationAdapter;
        this.submissionAdapter = submissionAdapter;
        setHasStableIds(true);
    }

    @CheckResult
    public Observable<SubredditSubmissionClickEvent> submissionClicks() {
        return submissionAdapter.submissionClicks();
    }

    @CheckResult
    public Observable<SubmissionGestureWalkthroughProceedEvent> gestureWalkthroughProceedClicks() {
        return gestureWalkthroughAdapter.proceedClicks();
    }

    @CheckResult
    public Observable<SubredditSubmissionThumbnailClickEvent> thumbnailClicks() {
        return submissionAdapter.thumbnailClicks();
    }

    @CheckResult
    public Observable<SwipeEvent> swipeEvents() {
        return submissionAdapter.swipeEvents();
    }

    @CheckResult
    public Observable<?> paginationFailureRetryClicks() {
        return paginationAdapter.failureRetryClicks();
    }

    @Override
    public long getItemId(int position) {
        return getItem(position).adapterId();
    }

    @Override
    public int getItemCountMinusDecorators() {
        int itemCount = getItemCount();
        if (itemCount > 1 && getItem(itemCount - 1).type() == SubmissionRowUiModel.Type.PAGINATION_FOOTER) {
            itemCount = itemCount - 1;
        }
        return itemCount;
    }

    @Override
    public int getItemViewType(int position) {
        return getItem(position).type().ordinal();
    }

    @Override
    protected RecyclerView.ViewHolder onCreateViewHolder(LayoutInflater inflater, ViewGroup parent, int viewType) {
        return childAdapters.get(VIEW_TYPES[viewType]).onCreateViewHolder(inflater, parent);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, List<Object> payloads) {
        if (payloads.isEmpty()) {
            super.onBindViewHolder(holder, position, payloads);
        } else {
            // noinspection unchecked
            childAdapters.get(VIEW_TYPES[holder.getItemViewType()]).onBindViewHolder(holder, getItem(position), payloads);
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        // noinspection unchecked
        childAdapters.get(VIEW_TYPES[holder.getItemViewType()]).onBindViewHolder(holder, getItem(position));
    }

    @Override
    public void accept(Pair<List<SubmissionRowUiModel>, DiffUtil.DiffResult> pair) {
        findCollidingIds(pair.first());
        updateData(pair.first());
        pair.second().dispatchUpdatesTo(this);
    }

{
        Map<Long, SubmissionRowUiModel> ids = new HashMap<>(rows.size(), 1f);
        for (SubmissionRowUiModel row : rows) {
            if (ids.containsKey(row.adapterId())) {
                SubmissionRowUiModel existing = ids.get(row.adapterId());
                throw new AssertionError("ID collision between " + existing + " and " + row);
            }
            ids.put(row.adapterId(), row);
        }
    }
}


{
        return childAdapters.get(VIEW_TYPES[viewType]).onCreateViewHolder(inflater, parent);
    }

package me.saket.dank.ui.subreddit;

import android.annotation.SuppressLint;
import android.support.annotation.CheckResult;
import android.support.v7.util.DiffUtil;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import io.reactivex.Observable;
import io.reactivex.functions.Consumer;
import me.saket.dank.data.SwipeEvent;
import me.saket.dank.ui.subreddit.events.SubredditSubmissionClickEvent;
import me.saket.dank.ui.subreddit.events.SubredditSubmissionThumbnailClickEvent;
import me.saket.dank.ui.subreddit.uimodels.SubredditScreenUiModel;
import me.saket.dank.ui.subreddit.uimodels.SubredditScreenUiModel.SubmissionRowUiModel;
import me.saket.dank.ui.subreddit.uimodels.SubredditSubmission;
import me.saket.dank.ui.subreddit.uimodels.SubredditSubmissionPagination;
import me.saket.dank.utils.InfinitelyScrollableRecyclerViewAdapter;
import me.saket.dank.utils.Pair;
import me.saket.dank.utils.RecyclerViewArrayAdapter;
import me.saket.dank.walkthrough.SubmissionGestureWalkthroughProceedEvent;
import me.saket.dank.walkthrough.SubmissionGesturesWalkthrough;

public class SubredditSubmissionsAdapter extends RecyclerViewArrayAdapter<SubmissionRowUiModel, RecyclerView.ViewHolder> implements Consumer<Pair<List<SubmissionRowUiModel>, DiffUtil.DiffResult>>, InfinitelyScrollableRecyclerViewAdapter {

    public static final int ADAPTER_ID_PAGINATION_FOOTER = -99;

    public static final long ADAPTER_ID_GESTURES_WALKTHROUGH = -98;

    private static final SubmissionRowUiModel.Type[] VIEW_TYPES = SubmissionRowUiModel.Type.values();

    private final Map<SubmissionRowUiModel.Type, SubredditScreenUiModel.SubmissionRowUiChildAdapter> childAdapters;

    private final SubredditSubmission.Adapter submissionAdapter;

    private final SubredditSubmissionPagination.Adapter paginationAdapter;

    private final SubmissionGesturesWalkthrough.Adapter gestureWalkthroughAdapter;

    @Inject
    public SubredditSubmissionsAdapter(SubmissionGesturesWalkthrough.Adapter gestureWalkthroughAdapter, SubredditSubmission.Adapter submissionAdapter, SubredditSubmissionPagination.Adapter paginationAdapter) {
        childAdapters = new HashMap<>(4);
        childAdapters.put(SubmissionRowUiModel.Type.GESTURES_WALKTHROUGH, gestureWalkthroughAdapter);
        childAdapters.put(SubmissionRowUiModel.Type.SUBMISSION, submissionAdapter);
        childAdapters.put(SubmissionRowUiModel.Type.PAGINATION_FOOTER, paginationAdapter);
        this.gestureWalkthroughAdapter = gestureWalkthroughAdapter;
        this.paginationAdapter = paginationAdapter;
        this.submissionAdapter = submissionAdapter;
        setHasStableIds(true);
    }

    @CheckResult
    public Observable<SubredditSubmissionClickEvent> submissionClicks() {
        return submissionAdapter.submissionClicks();
    }

    @CheckResult
    public Observable<SubmissionGestureWalkthroughProceedEvent> gestureWalkthroughProceedClicks() {
        return gestureWalkthroughAdapter.proceedClicks();
    }

    @CheckResult
    public Observable<SubredditSubmissionThumbnailClickEvent> thumbnailClicks() {
        return submissionAdapter.thumbnailClicks();
    }

    @CheckResult
    public Observable<SwipeEvent> swipeEvents() {
        return submissionAdapter.swipeEvents();
    }

    @CheckResult
    public Observable<?> paginationFailureRetryClicks() {
        return paginationAdapter.failureRetryClicks();
    }

    @Override
    public long getItemId(int position) {
        return getItem(position).adapterId();
    }

    @Override
    public int getItemCountMinusDecorators() {
        int itemCount = getItemCount();
        if (itemCount > 1 && getItem(itemCount - 1).type() == SubmissionRowUiModel.Type.PAGINATION_FOOTER) {
            itemCount = itemCount - 1;
        }
        return itemCount;
    }

    @Override
    public int getItemViewType(int position) {
        return getItem(position).type().ordinal();
    }

    @Override
    protected RecyclerView.ViewHolder onCreateViewHolder(LayoutInflater inflater, ViewGroup parent, int viewType)

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, List<Object> payloads) {
        if (payloads.isEmpty()) {
            super.onBindViewHolder(holder, position, payloads);
        } else {
            // noinspection unchecked
            childAdapters.get(VIEW_TYPES[holder.getItemViewType()]).onBindViewHolder(holder, getItem(position), payloads);
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        // noinspection unchecked
        childAdapters.get(VIEW_TYPES[holder.getItemViewType()]).onBindViewHolder(holder, getItem(position));
    }

    @Override
    public void accept(Pair<List<SubmissionRowUiModel>, DiffUtil.DiffResult> pair) {
        findCollidingIds(pair.first());
        updateData(pair.first());
        pair.second().dispatchUpdatesTo(this);
    }

    @SuppressLint("UseSparseArrays")
    private static void findCollidingIds(List<SubmissionRowUiModel> rows) {
        Map<Long, SubmissionRowUiModel> ids = new HashMap<>(rows.size(), 1f);
        for (SubmissionRowUiModel row : rows) {
            if (ids.containsKey(row.adapterId())) {
                SubmissionRowUiModel existing = ids.get(row.adapterId());
                throw new AssertionError("ID collision between " + existing + " and " + row);
            }
            ids.put(row.adapterId(), row);
        }
    }
}


package me.saket.dank.ui.subreddit;

import android.annotation.SuppressLint;
import android.support.annotation.CheckResult;
import android.support.v7.util.DiffUtil;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import io.reactivex.Observable;
import io.reactivex.functions.Consumer;
import me.saket.dank.data.SwipeEvent;
import me.saket.dank.ui.subreddit.events.SubredditSubmissionClickEvent;
import me.saket.dank.ui.subreddit.events.SubredditSubmissionThumbnailClickEvent;
import me.saket.dank.ui.subreddit.uimodels.SubredditScreenUiModel;
import me.saket.dank.ui.subreddit.uimodels.SubredditScreenUiModel.SubmissionRowUiModel;
import me.saket.dank.ui.subreddit.uimodels.SubredditSubmission;
import me.saket.dank.ui.subreddit.uimodels.SubredditSubmissionPagination;
import me.saket.dank.utils.InfinitelyScrollableRecyclerViewAdapter;
import me.saket.dank.utils.Pair;
import me.saket.dank.utils.RecyclerViewArrayAdapter;
import me.saket.dank.walkthrough.SubmissionGestureWalkthroughProceedEvent;
import me.saket.dank.walkthrough.SubmissionGesturesWalkthrough;

public class SubredditSubmissionsAdapter extends RecyclerViewArrayAdapter<SubmissionRowUiModel, RecyclerView.ViewHolder> implements Consumer<Pair<List<SubmissionRowUiModel>, DiffUtil.DiffResult>>, InfinitelyScrollableRecyclerViewAdapter {

    public static final int ADAPTER_ID_PAGINATION_FOOTER = -99;

    public static final long ADAPTER_ID_GESTURES_WALKTHROUGH = -98;

    private static final SubmissionRowUiModel.Type[] VIEW_TYPES = SubmissionRowUiModel.Type.values();

    private final Map<SubmissionRowUiModel.Type, SubredditScreenUiModel.SubmissionRowUiChildAdapter> childAdapters;

    private final SubredditSubmission.Adapter submissionAdapter;

    private final SubredditSubmissionPagination.Adapter paginationAdapter;

    private final SubmissionGesturesWalkthrough.Adapter gestureWalkthroughAdapter;

    @Inject
    public SubredditSubmissionsAdapter(SubmissionGesturesWalkthrough.Adapter gestureWalkthroughAdapter, SubredditSubmission.Adapter submissionAdapter, SubredditSubmissionPagination.Adapter paginationAdapter) {
        childAdapters = new HashMap<>(4);
        childAdapters.put(SubmissionRowUiModel.Type.GESTURES_WALKTHROUGH, gestureWalkthroughAdapter);
        childAdapters.put(SubmissionRowUiModel.Type.SUBMISSION, submissionAdapter);
        childAdapters.put(SubmissionRowUiModel.Type.PAGINATION_FOOTER, paginationAdapter);
        this.gestureWalkthroughAdapter = gestureWalkthroughAdapter;
        this.paginationAdapter = paginationAdapter;
        this.submissionAdapter = submissionAdapter;
        setHasStableIds(true);
    }

    @CheckResult
    public Observable<SubredditSubmissionClickEvent> submissionClicks() {
        return submissionAdapter.submissionClicks();
    }

    @CheckResult
    public Observable<SubmissionGestureWalkthroughProceedEvent> gestureWalkthroughProceedClicks() {
        return gestureWalkthroughAdapter.proceedClicks();
    }

    @CheckResult
    public Observable<SubredditSubmissionThumbnailClickEvent> thumbnailClicks() {
        return submissionAdapter.thumbnailClicks();
    }

    @CheckResult
    public Observable<SwipeEvent> swipeEvents() {
        return submissionAdapter.swipeEvents();
    }

    @CheckResult
    public Observable<?> paginationFailureRetryClicks() {
        return paginationAdapter.failureRetryClicks();
    }

    @Override
    public long getItemId(int position) {
        return getItem(position).adapterId();
    }

    @Override
    public int getItemCountMinusDecorators() {
        int itemCount = getItemCount();
        if (itemCount > 1 && getItem(itemCount - 1).type() == SubmissionRowUiModel.Type.PAGINATION_FOOTER) {
            itemCount = itemCount - 1;
        }
        return itemCount;
    }

    @Override
    public int getItemViewType(int position) {
        return getItem(position).type().ordinal();
    }

    @Override
    protected RecyclerView.ViewHolder onCreateViewHolder(LayoutInflater inflater, ViewGroup parent, int viewType) {
        return childAdapters.get(VIEW_TYPES[viewType]).onCreateViewHolder(inflater, parent);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, List<Object> payloads) {

        if (payloads.isEmpty()) {
            super.onBindViewHolder(holder, position, payloads);
        } else {
            // noinspection unchecked
            childAdapters.get(VIEW_TYPES[holder.getItemViewType()]).onBindViewHolder(holder, getItem(position), payloads);
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        // noinspection unchecked
        childAdapters.get(VIEW_TYPES[holder.getItemViewType()]).onBindViewHolder(holder, getItem(position));
    }

    @Override
    public void accept(Pair<List<SubmissionRowUiModel>, DiffUtil.DiffResult> pair) {
        findCollidingIds(pair.first());
        updateData(pair.first());
        pair.second().dispatchUpdatesTo(this);
    }

    @SuppressLint("UseSparseArrays")
    private static void findCollidingIds(List<SubmissionRowUiModel> rows) {
        Map<Long, SubmissionRowUiModel> ids = new HashMap<>(rows.size(), 1f);
        for (SubmissionRowUiModel row : rows) {
            if (ids.containsKey(row.adapterId())) {
                SubmissionRowUiModel existing = ids.get(row.adapterId());
                throw new AssertionError("ID collision between " + existing + " and " + row);
            }
            ids.put(row.adapterId(), row);
        }
    }
}


if (payloads.isEmpty()) {
            super.onBindViewHolder(holder, position, payloads);
        } else {
            // noinspection unchecked
            childAdapters.get(VIEW_TYPES[holder.getItemViewType()]).onBindViewHolder(holder, getItem(position), payloads);
        }

    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        // noinspection unchecked
        childAdapters.get(VIEW_TYPES[holder.getItemViewType()]).onBindViewHolder(holder, getItem(position));
    }

    @Override
    public void accept(Pair<List<SubmissionRowUiModel>, DiffUtil.DiffResult> pair) {
        findCollidingIds(pair.first());
        updateData(pair.first());
        pair.second().dispatchUpdatesTo(this);
    }

    @SuppressLint("UseSparseArrays")
    private static void findCollidingIds(List<SubmissionRowUiModel> rows) {
        Map<Long, SubmissionRowUiModel> ids = new HashMap<>(rows.size(), 1f);
        for (SubmissionRowUiModel row : rows) {
            if (ids.containsKey(row.adapterId())) {
                SubmissionRowUiModel existing = ids.get(row.adapterId());
                throw new AssertionError("ID collision between " + existing + " and " + row);
            }
            ids.put(row.adapterId(), row);
        }
    }
}


package me.saket.dank.ui.subreddit;

import android.annotation.SuppressLint;
import android.support.annotation.CheckResult;
import android.support.v7.util.DiffUtil;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import io.reactivex.Observable;
import io.reactivex.functions.Consumer;
import me.saket.dank.data.SwipeEvent;
import me.saket.dank.ui.subreddit.events.SubredditSubmissionClickEvent;
import me.saket.dank.ui.subreddit.events.SubredditSubmissionThumbnailClickEvent;
import me.saket.dank.ui.subreddit.uimodels.SubredditScreenUiModel;
import me.saket.dank.ui.subreddit.uimodels.SubredditScreenUiModel.SubmissionRowUiModel;
import me.saket.dank.ui.subreddit.uimodels.SubredditSubmission;
import me.saket.dank.ui.subreddit.uimodels.SubredditSubmissionPagination;
import me.saket.dank.utils.InfinitelyScrollableRecyclerViewAdapter;
import me.saket.dank.utils.Pair;
import me.saket.dank.utils.RecyclerViewArrayAdapter;
import me.saket.dank.walkthrough.SubmissionGestureWalkthroughProceedEvent;
import me.saket.dank.walkthrough.SubmissionGesturesWalkthrough;

public class SubredditSubmissionsAdapter extends RecyclerViewArrayAdapter<SubmissionRowUiModel, RecyclerView.ViewHolder> implements Consumer<Pair<List<SubmissionRowUiModel>, DiffUtil.DiffResult>>, InfinitelyScrollableRecyclerViewAdapter {

    public static final int ADAPTER_ID_PAGINATION_FOOTER = -99;

    public static final long ADAPTER_ID_GESTURES_WALKTHROUGH = -98;

    private static final SubmissionRowUiModel.Type[] VIEW_TYPES = SubmissionRowUiModel.Type.values();

    private final Map<SubmissionRowUiModel.Type, SubredditScreenUiModel.SubmissionRowUiChildAdapter> childAdapters;

    private final SubredditSubmission.Adapter submissionAdapter;

    private final SubredditSubmissionPagination.Adapter paginationAdapter;

    private final SubmissionGesturesWalkthrough.Adapter gestureWalkthroughAdapter;

    @Inject
    public SubredditSubmissionsAdapter(SubmissionGesturesWalkthrough.Adapter gestureWalkthroughAdapter, SubredditSubmission.Adapter submissionAdapter, SubredditSubmissionPagination.Adapter paginationAdapter) {
        childAdapters = new HashMap<>(4);
        childAdapters.put(SubmissionRowUiModel.Type.GESTURES_WALKTHROUGH, gestureWalkthroughAdapter);
        childAdapters.put(SubmissionRowUiModel.Type.SUBMISSION, submissionAdapter);
        childAdapters.put(SubmissionRowUiModel.Type.PAGINATION_FOOTER, paginationAdapter);
        this.gestureWalkthroughAdapter = gestureWalkthroughAdapter;
        this.paginationAdapter = paginationAdapter;
        this.submissionAdapter = submissionAdapter;
        setHasStableIds(true);
    }

    @CheckResult
    public Observable<SubredditSubmissionClickEvent> submissionClicks() {
        return submissionAdapter.submissionClicks();
    }

    @CheckResult
    public Observable<SubmissionGestureWalkthroughProceedEvent> gestureWalkthroughProceedClicks() {
        return gestureWalkthroughAdapter.proceedClicks();
    }

    @CheckResult
    public Observable<SubredditSubmissionThumbnailClickEvent> thumbnailClicks() {
        return submissionAdapter.thumbnailClicks();
    }

    @CheckResult
    public Observable<SwipeEvent> swipeEvents() {
        return submissionAdapter.swipeEvents();
    }

    @CheckResult
    public Observable<?> paginationFailureRetryClicks() {
        return paginationAdapter.failureRetryClicks();
    }

    @Override
    public long getItemId(int position) {
        return getItem(position).adapterId();
    }

    @Override
    public int getItemCountMinusDecorators() {
        int itemCount = getItemCount();
        if (itemCount > 1 && getItem(itemCount - 1).type() == SubmissionRowUiModel.Type.PAGINATION_FOOTER) {
            itemCount = itemCount - 1;
        }
        return itemCount;
    }

    @Override
    public int getItemViewType(int position) {
        return getItem(position).type().ordinal();
    }

    @Override
    protected RecyclerView.ViewHolder onCreateViewHolder(LayoutInflater inflater, ViewGroup parent, int viewType) {
        return childAdapters.get(VIEW_TYPES[viewType]).onCreateViewHolder(inflater, parent);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, List<Object> payloads) {
        if (payloads.isEmpty()) {
            super.onBindViewHolder(holder, position, payloads);
        } else {
            // noinspection unchecked
            childAdapters.get(VIEW_TYPES[holder.getItemViewType()]).onBindViewHolder(holder, getItem(position), payloads);
        }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        // noinspection unchecked
        childAdapters.get(VIEW_TYPES[holder.getItemViewType()]).onBindViewHolder(holder, getItem(position));
    }

    @Override
    public void accept(Pair<List<SubmissionRowUiModel>, DiffUtil.DiffResult> pair) {
        findCollidingIds(pair.first());
        updateData(pair.first());
        pair.second().dispatchUpdatesTo(this);
    }

    @SuppressLint("UseSparseArrays")
    private static void findCollidingIds(List<SubmissionRowUiModel> rows) {
        Map<Long, SubmissionRowUiModel> ids = new HashMap<>(rows.size(), 1f);
        for (SubmissionRowUiModel row : rows) {
            if (ids.containsKey(row.adapterId())) {
                SubmissionRowUiModel existing = ids.get(row.adapterId());
                throw new AssertionError("ID collision between " + existing + " and " + row);
            }
            ids.put(row.adapterId(), row);
        }
    }
}


package me.saket.dank.ui.subreddit;

import android.annotation.SuppressLint;
import android.support.annotation.CheckResult;
import android.support.v7.util.DiffUtil;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import io.reactivex.Observable;
import io.reactivex.functions.Consumer;
import me.saket.dank.data.SwipeEvent;
import me.saket.dank.ui.subreddit.events.SubredditSubmissionClickEvent;
import me.saket.dank.ui.subreddit.events.SubredditSubmissionThumbnailClickEvent;
import me.saket.dank.ui.subreddit.uimodels.SubredditScreenUiModel;
import me.saket.dank.ui.subreddit.uimodels.SubredditScreenUiModel.SubmissionRowUiModel;
import me.saket.dank.ui.subreddit.uimodels.SubredditSubmission;
import me.saket.dank.ui.subreddit.uimodels.SubredditSubmissionPagination;
import me.saket.dank.utils.InfinitelyScrollableRecyclerViewAdapter;
import me.saket.dank.utils.Pair;
import me.saket.dank.utils.RecyclerViewArrayAdapter;
import me.saket.dank.walkthrough.SubmissionGestureWalkthroughProceedEvent;
import me.saket.dank.walkthrough.SubmissionGesturesWalkthrough;

public class SubredditSubmissionsAdapter extends RecyclerViewArrayAdapter<SubmissionRowUiModel, RecyclerView.ViewHolder> implements Consumer<Pair<List<SubmissionRowUiModel>, DiffUtil.DiffResult>>, InfinitelyScrollableRecyclerViewAdapter {

    public static final int ADAPTER_ID_PAGINATION_FOOTER = -99;

    public static final long ADAPTER_ID_GESTURES_WALKTHROUGH = -98;

    private static final SubmissionRowUiModel.Type[] VIEW_TYPES = SubmissionRowUiModel.Type.values();

    private final Map<SubmissionRowUiModel.Type, SubredditScreenUiModel.SubmissionRowUiChildAdapter> childAdapters;

    private final SubredditSubmission.Adapter submissionAdapter;

    private final SubredditSubmissionPagination.Adapter paginationAdapter;

    private final SubmissionGesturesWalkthrough.Adapter gestureWalkthroughAdapter;

    @Inject
    public SubredditSubmissionsAdapter(SubmissionGesturesWalkthrough.Adapter gestureWalkthroughAdapter, SubredditSubmission.Adapter submissionAdapter, SubredditSubmissionPagination.Adapter paginationAdapter) {
        childAdapters = new HashMap<>(4);
        childAdapters.put(SubmissionRowUiModel.Type.GESTURES_WALKTHROUGH, gestureWalkthroughAdapter);
        childAdapters.put(SubmissionRowUiModel.Type.SUBMISSION, submissionAdapter);
        childAdapters.put(SubmissionRowUiModel.Type.PAGINATION_FOOTER, paginationAdapter);
        this.gestureWalkthroughAdapter = gestureWalkthroughAdapter;
        this.paginationAdapter = paginationAdapter;
        this.submissionAdapter = submissionAdapter;
        setHasStableIds(true);
    }

    @CheckResult
    public Observable<SubredditSubmissionClickEvent> submissionClicks() {
        return submissionAdapter.submissionClicks();
    }

    @CheckResult
    public Observable<SubmissionGestureWalkthroughProceedEvent> gestureWalkthroughProceedClicks() {
        return gestureWalkthroughAdapter.proceedClicks();
    }

    @CheckResult
    public Observable<SubredditSubmissionThumbnailClickEvent> thumbnailClicks() {
        return submissionAdapter.thumbnailClicks();
    }

    @CheckResult
    public Observable<SwipeEvent> swipeEvents() {
        return submissionAdapter.swipe

    }

    @CheckResult
    public Observable<?> paginationFailureRetryClicks() {
        return paginationAdapter.failureRetryClicks();
    }

    @Override
    public long getItemId(int position) {
        return getItem(position).adapterId();
    }

    @Override
    public int getItemCountMinusDecorators() {
        int itemCount = getItemCount();
        if (itemCount > 1 && getItem(itemCount - 1).type() == SubmissionRowUiModel.Type.PAGINATION_FOOTER) {
            itemCount = itemCount - 1;
        }
        return itemCount;
    }

    @Override
    public int getItemViewType(int position) {
        return getItem(position).type().ordinal();
    }

    @Override
    protected RecyclerView.ViewHolder onCreateViewHolder(LayoutInflater inflater, ViewGroup parent, int viewType) {
        return childAdapters.get(VIEW_TYPES[viewType]).onCreateViewHolder(inflater, parent);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, List<Object> payloads) {
        if (payloads.isEmpty()) {
            super.onBindViewHolder(holder, position, payloads);
        } else {
            // noinspection unchecked
            childAdapters.get(VIEW_TYPES[holder.getItemViewType()]).onBindViewHolder(holder, getItem(position), payloads);
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        // noinspection unchecked
        childAdapters.get(VIEW_TYPES[holder.getItemViewType()]).onBindViewHolder(holder, getItem(position));
    }

    @Override
    public void accept(Pair<List<SubmissionRowUiModel>, DiffUtil.DiffResult> pair) {
        findCollidingIds(pair.first());
        updateData(pair.first());
        pair.second().dispatchUpdatesTo(this);
    }

    @SuppressLint("UseSparseArrays")
    private static void findCollidingIds(List<SubmissionRowUiModel> rows) {
        Map<Long, SubmissionRowUiModel> ids = new HashMap<>(rows.size(), 1f);
        for (SubmissionRowUiModel row : rows) {
            if (ids.containsKey(row.adapterId())) {
                SubmissionRowUiModel existing = ids.get(row.adapterId());
                throw new AssertionError("ID collision between " + existing + " and " + row);
            }
            ids.put(row.adapterId(), row);
        }
    }
}