text:
package de.undercouch.gradle.tasks.download;

import groovy.lang.Closure;
import kotlin.jvm.functions.Function0;
import org.apache.commons.io.FileUtils;
import org.gradle.api.file.RelativePath;
import org.gradle.api.internal.provider.DefaultProvider;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicInteger;

import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.fail;

/**
 * Tests the gradle-download-task plugin
 * @author Michel Kraemer
 */
public class DownloadTest extends TestBaseWithMockServer {
    /**
     * Create a WireMock stub for {@link #TEST_FILE_NAME} with {@link #CONTENTS}
     * and {@link #TEST_FILE_NAME2} with {@link #CONTENTS2}
     */
    @BeforeEach
    public void stubForTestFile() {
        stubFor(get(urlEqualTo("/" + TEST_FILE_NAME))
                .willReturn(aResponse()
                        .withHeader("content-length", String.valueOf(CONTENTS.length()))
                        .withBody(CONTENTS)));
        stubFor(get(urlEqualTo("/" + TEST_FILE_NAME2))
                .willReturn(aResponse()
                        .withHeader("content-length", String.valueOf(CONTENTS2.length()))
                        .withBody(CONTENTS2)));
    }

    /**
     * Tests if a single file can be downloaded
     * @throws Exception if anything goes wrong
     */
    @Test
    public void downloadSingleFile() throws Exception {
        Download t = makeProjectAndTask();
        String src = wireMock.url(TEST_FILE_NAME);
        t.src(src);
        File dst = newTempFile();
        t.dest(dst);
        execute(t);

        assertThat(t.getSrc()).isInstanceOf(URL.class);
        assertThat(t.getSrc().toString()).isEqualTo(src);
        assertThat(t.getDest()).isSameAs(dst);

        assertThat(dst).usingCharset(StandardCharsets.UTF_8).hasContent(CONTENTS);
    }

    /**
     * Tests if a single file can be downloaded from a URL
     * @throws Exception if anything goes wrong
     */
    @Test
    public void downloadSingleURL() throws Exception {
        Download t = makeProjectAndTask();
        URL src = new URL(wireMock.url(TEST_FILE_NAME));
        t.src(src);
        File dst = newTempFile();
        t.dest(dst);
        execute(t);

        assertThat(t.getSrc()).isSameAs(src);
        assertThat(t.getDest()).isSameAs(dst);

        assertThat(dst).usingCharset(StandardCharsets.UTF_8).hasContent(CONTENTS);
    }

    /**
     * Tests if a single file can be downloaded to a directory
     * @throws Exception if anything goes wrong
     */
    @Test
    public void downloadSingleFileToDir() throws Exception {
        Download t = makeProjectAndTask();
        t.src(wireMock.url(TEST_FILE_NAME));
        File dst = newTempDir();
        t.dest(dst);
        execute(t);

        assertThat(new File(dst, TEST_FILE_NAME))
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS);
    }

    /**
     * Tests if a file is downloaded to the project directory when specifying
     * a relative path
     */
    @Test
    public void downloadSingleFileToRelativePath() {
        Download t = makeProjectAndTask();
        t.src(wireMock.url(TEST_FILE_NAME));
        t.dest(TEST_FILE_NAME);
        execute(t);

        assertThat(new File(projectDir, TEST_FILE_NAME))
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS);
    }

    /**
     * Tests if multiple files can be downloaded to a directory
     * @throws Exception if anything goes wrong
     */
    @Test
    public void downloadMultipleFiles() throws Exception {
        Download t = makeProjectAndTask();
        t.src(Arrays.asList(wireMock.url(TEST_FILE_NAME),
                wireMock.url(TEST_FILE_NAME2)));

        File dst = newTempDir();
        t.dest(dst);
        execute(t);

        assertThat(new File(dst, TEST_FILE_NAME))
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS);
        assertThat(new File(dst, TEST_FILE_NAME2))
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS2);
    }

    /**
     * Tests if a destination directory is automatically created if multiple
     * files are downloaded
     * @throws Exception if anything goes wrong
     */
    @Test
    public void downloadMultipleFilesCreatesDestDirAutomatically() throws Exception {
        Download t = makeProjectAndTask();
        t.src(Arrays.asList(wireMock.url(TEST_FILE_NAME),
                wireMock.url(TEST_FILE_NAME2)));

        File dst = newTempDir();
        assertThat(dst.delete()).isTrue();
        t.dest(dst);
        execute(t);
        assertThat(dst).isDirectory();
    }

    /**
     * Tests if the task throws an exception if you try to download
     * multiple files to a single destination file
     * @throws Exception if anything goes wrong
     */
    @Test
    public void downloadMultipleFilesToFile() throws Exception {
        Download t = makeProjectAndTask();
        t.src(Arrays.asList(wireMock.url(TEST_FILE_NAME),
                wireMock.url(TEST_FILE_NAME2)));
        File dst = newTempFile();
        t.dest(dst);
        assertThatThrownBy(() -> execute(t))
                .isInstanceOf(IllegalArgumentException.class)
                .hasMessageContaining("the destination has to be a directory");
    }

    /**
     * Tests lazy evaluation of 'src' and 'dest' properties
     * @throws Exception if anything goes wrong
     */
    @Test
    public void lazySrcAndDest() throws Exception {
        final boolean[] srcCalled = new boolean[] { false };
        final boolean[] dstCalled = new boolean[] { false };

        final File dst = newTempFile();

        Download t = makeProjectAndTask();
        t.src(new Closure<Object>(this, this) {
            private static final long serialVersionUID = -4463658999363261400L;

            @SuppressWarnings("unused")
            public Object doCall() {
                srcCalled[0] = true;
                return wireMock.url(TEST_FILE_NAME);
            }
        });

        t.dest(new Closure<Object>(this, this) {
            private static final long serialVersionUID = 932174549047352157L;

            @SuppressWarnings("unused")
            public Object doCall() {
                dstCalled[0] = true;
                return dst;
            }
        });

        assertThat(srcCalled[0]).isFalse();
        assertThat(dstCalled[0]).isFalse();

        execute(t);

        assertThat(srcCalled[0]).isTrue();
        assertThat(dstCalled[0]).isTrue();

        assertThat(dst).usingCharset(StandardCharsets.UTF_8).hasContent(CONTENTS);
    }

    /**
     * Tests lazy evaluation of 'src' and 'dest' properties if they are
     * Providers
     * @throws Exception if anything goes wrong
     */
    @Test
    public void providerSrcAndDest() throws Exception {
        final boolean[] srcCalled = new boolean[] { false };
        final boolean[] dstCalled = new boolean[] { false };

        final File dst = newTempFile();

        Download t = makeProjectAndTask();
        t.src(new DefaultProvider<>((Callable<Object>)() -> {
            srcCalled[0] = true;
            return wireMock.url(TEST_FILE_NAME);
        }));

        t.dest(new DefaultProvider<>((Callable<Object>)() -> {
            dstCalled[0] = true;
            return dst;
        }));

        assertThat(srcCalled[0]).isFalse();
        assertThat(dstCalled[0]).isFalse();

        execute(t);

        assertThat(srcCalled[0]).isTrue();
        assertThat(dstCalled[0]).isTrue();

        assertThat(dst).usingCharset(StandardCharsets.UTF_8).hasContent(CONTENTS);
    }

    /**
     * Tests lazy evaluation of 'src' and 'dest' properties if they are
     * Kotlin Functions
     * @throws Exception if anything goes wrong
     */
    @Test
    public void kotlinFunctionSrcAndDest() throws Exception {
        final boolean[] srcCalled = new boolean[] { false };
        final boolean[] dstCalled = new boolean[] { false };

        final File dst = newTempFile();

        Download t = makeProjectAndTask();
        t.src((Function0<Object>)() -> {
            srcCalled[0] = true;
            return wireMock.url(TEST_FILE_NAME);
        });

        t.dest((Function0<Object>)() -> {
            dstCalled[0] = true;
            return dst;
        });

        assertThat(srcCalled[0]).isFalse();
        assertThat(dstCalled[0]).isFalse();

        execute(t);

        assertThat(srcCalled[0]).isTrue();
        assertThat(dstCalled[0]).isTrue();

        assertThat(dst).usingCharset(StandardCharsets.UTF_8).hasContent(CONTENTS);
    }

    /**
     * Test if cached sources are updated properly
     * @throws Exception if anything goes wrong
     */
    @Test
    public void updateCachedSources() throws Exception {
        final AtomicInteger srcCalled = new AtomicInteger();

        final File dst = newTempDir();

        Download t = makeProjectAndTask();
        t.src(new Closure<Object>(this, this) {
            private static final long serialVersionUID = -4463658999363261400L;

            @SuppressWarnings("unused")
            public Object doCall() {
                srcCalled.incrementAndGet();
                return wireMock.url(TEST_FILE_NAME);
            }
        });

        assertThat(srcCalled.get()).isEqualTo(0);

        // calling t.getSrc() will call our closure and cache the result
        assertThat(t.getSrc()).isInstanceOf(URL.class);
        assertThat(srcCalled.get()).isEqualTo(1);

        // add another src
        t.src(wireMock.url(TEST_FILE_NAME2));

        // getSrc() should return the updated sources but our closure should
        // still have only been called once
        assertThat(t.getSrc()).isInstanceOf(List.class);
        assertThat(srcCalled.get()).isEqualTo(1);

        t.dest(dst);

        execute(t);

        assertThat(new File(dst, TEST_FILE_NAME))
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS);
        assertThat(new File(dst, TEST_FILE_NAME2))
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS2);
    }

    /**
     * Make sure eachFile actions are called only once
     * @throws Exception if anything goes wrong
     */
    @Test
    public void eachFileCalledOnce() throws Exception {
        final AtomicInteger eachFileCalled = new AtomicInteger();

        final File dst = newTempDir();
        File destFile1 = new File(dst, TEST_FILE_NAME);
        File destFile2 = new File(dst, TEST_FILE_NAME2);

        Download t = makeProjectAndTask();
        String u1 = wireMock.url(TEST_FILE_NAME);
        String u2 = wireMock.url(TEST_FILE_NAME2);
        t.src(Arrays.asList(u1, u2));
        t.dest(dst);
        t.eachFile(f -> eachFileCalled.incrementAndGet());

        assertThat(eachFileCalled.get()).isEqualTo(0);

        // calling t.getOutputFiles() will call the eachFile action (once for
        // each source) and cache the result
        assertThat(t.getOutputFiles()).isEqualTo(Arrays.asList(destFile1, destFile2));
        assertThat(eachFileCalled.get()).isEqualTo(2);

        // call it again, the eachFile action should not be called again
        assertThat(t.getOutputFiles()).isEqualTo(Arrays.asList(destFile1, destFile2));
        assertThat(eachFileCalled.get()).isEqualTo(2);

        execute(t);

        assertThat(destFile1)
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS);
        assertThat(destFile2)
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS2);

        // eachFile action should not have been called again
        assertThat(eachFileCalled.get()).isEqualTo(2);
    }

    /**
     * Test if the cached list of output files is updated properly
     * @throws Exception if anything goes wrong
     */
    @Test
    public void updateCachedOutputFiles() throws Exception {
        final AtomicInteger eachFileCalled = new AtomicInteger();

        final File dst = newTempDir();
        File destFile1 = new File(dst, TEST_FILE_NAME + ".1");
        File destFile2 = new File(dst, TEST_FILE_NAME2 + ".2");
        File destFile3 = new File(dst, TEST_FILE_NAME2 + ".3");

        Download t = makeProjectAndTask();
        String u1 = wireMock.url(TEST_FILE_NAME);
        String u2 = wireMock.url(TEST_FILE_NAME2);
        t.src(Arrays.asList(u1, u2));
        t.dest(dst);
        t.eachFile(f -> f.setName(f.getName() + "." + eachFileCalled.incrementAndGet()));

        assertThat(eachFileCalled.get()).isEqualTo(0);

        // t.getOutputFiles() will call the eachFile action (once for each
        // source) and cache the result
        assertThat(t.getOutputFiles()).isEqualTo(Arrays.asList(destFile1, destFile2));
        assertThat(eachFileCalled.get()).isEqualTo(2);

        // add another src
        t.src(wireMock.url(TEST_FILE_NAME2));

        // t.getOutputFiles() will now call the eachFile action again for the
        // new source and then cache the new result
        assertThat(t.getOutputFiles()).isEqualTo(Arrays.asList(destFile1, destFile2, destFile3));
        assertThat(eachFileCalled.get()).isEqualTo(3);

        t.dest(dst);

        execute(t);

        assertThat(destFile1)
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS);
        assertThat(destFile2)
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS2);
        assertThat(destFile3)
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS2);

        // the eachFile action should still have been called only three times
        assertThat(eachFileCalled.get()).isEqualTo(3);
    }

    /**
     * Do not overwrite an existing file
     * @throws Exception if anything goes wrong
     */
    @Test
    public void skipExisting() throws Exception {
        // write contents to destination file
        File dst = newTempFile();
        FileUtils.writeStringToFile(dst, "Hello", StandardCharsets.UTF_8);

        Download t = makeProjectAndTask();
        String src = wireMock.url(TEST_FILE_NAME);
        t.src(src);
        t.dest(dst);
        t.overwrite(false); // do not overwrite the file
        execute(t);

        // contents must not be changed
        assertThat(dst).usingCharset(StandardCharsets.UTF_8).hasContent("Hello");
    }

    /**
     * Test if the plugin throws an exception if the 'src' property is invalid
     * @throws Exception if the test succeeds
     */
    @Test
    public void testInvalidSrc() throws Exception {
        Download t = makeProjectAndTask();
        t.src(new Object());
        t.dest(newTempFile());
        assertThatThrownBy(() -> execute(t))
                .isInstanceOf(IllegalArgumentException.class)
                .hasMessageContaining("Download source must either be");
    }

    /**
     * Test if the plugin throws an exception if the 'src' property is empty
     */
    @Test
    public void testExecuteEmptySrc() {
        Download t = makeProjectAndTask();
        assertThatThrownBy(() -> execute(t))
                .isInstanceOf(IllegalArgumentException.class)
                .hasMessage("Please provide a download source");
    }

    /**
     * Test if the plugin throws an exception if the 'dest' property is invalid
     */
    @Test
    public void testInvalidDest() {
        Download t = makeProjectAndTask();
        String src = wireMock.url(TEST_FILE_NAME);
        t.src(src);
        t.dest(new Object());
        assertThatThrownBy(() -> execute(t))
                .isInstanceOf(IllegalArgumentException.class)
                .hasMessageContaining("Download destination must be one of");
    }

    /**
     * Test if the plugin throws an exception if the 'dest' property is empty
     */
    @Test
    public void testExecuteEmptyDest() {
        Download t = makeProjectAndTask();
        String src = wireMock.url(TEST_FILE_NAME);
        t.src(src);
        assertThatThrownBy(() -> execute(t))
                .isInstanceOf(IllegalArgumentException.class)
                .hasMessage("Please provide a download destination");
    }

    /**
     * Test if the plugin can handle an array containing one string as source
     */
    @Test
    public void testArraySrc() {
        Download t = makeProjectAndTask();
        String src = wireMock.url(TEST_FILE_NAME);
        t.src(new Object[] { src });
        assertThat(t.getSrc()).isInstanceOf(URL.class);
    }

    /**
     * Test if a file can be "downloaded" from a file:// url
     * @throws Exception if anything goes wrong
     */
    @Test
    public void testFileDownloadURL() throws Exception {
        Download t = makeProjectAndTask();

        String testContent = "file content";
        File src = newTempFile();
        FileUtils.writeStringToFile(src, testContent, "UTF-8");

        URL url = src.toURI().toURL();

        File dst = newTempFile();
        assertThat(dst.delete()).isTrue();

        t.src(new Object[] { url.toExternalForm() });
        t.dest(dst);
        execute(t);

        String content = FileUtils.readFileToString(dst, "UTF-8");
        assertThat(content).isEqualTo(testContent);
    }

    /**
     * Test if a file can be "downloaded" from a file:// url with the
     * overwrite flag set to true
     * @throws Exception if anything goes wrong
     */
    @Test
    public void testFileDownloadURLOverwriteTrue() throws Exception {
        Download t = makeProjectAndTask();

        String testContent = "file content";
        File src = newTempFile();
        FileUtils.writeStringToFile(src, testContent, "UTF-8");

        URL url = src.toURI().toURL();

        File dst = newTempFile();
        assertThat(dst).exists();

        t.src(new Object[] { url.toExternalForm() });
        t.dest(dst);
        t.overwrite(true);
        execute(t);

        String content = FileUtils.readFileToString(dst, "UTF-8");
        assertThat(content).isEqualTo(testContent);
    }

    /**
     * Tests if specifying an eachFile action leads to an exception if only
     * one source is given
     * @throws Exception if anything goes wrong
     */
    @Test
    public void eachFileActionSingleSource() throws Exception {
        Download t = makeProjectAndTask();
        t.src(wireMock.url(TEST_FILE_NAME));
        t.dest(newTempFile());
        t.eachFile(details -> {
            fail("We should never get here");
        });
        assertThatThrownBy(() -> execute(t))
                .isInstanceOf(IllegalArgumentException.class)
                .hasMessageContaining("eachFile");
    }

    /**
     * Tests if we can catch an exception from an eachFile action
     * @throws Exception if anything goes wrong
     */
    @Test
    public void eachFileActionThrows() throws Exception {
        Download t = makeProjectAndTask();
        t.src(Arrays.asList(wireMock.url(TEST_FILE_NAME), wireMock.url(TEST_FILE_NAME2)));
        t.dest(newTempDir());
        t.eachFile(details -> {
            throw new RuntimeException("Dummy");
        });
        assertThatThrownBy(() -> execute(t))
                .isInstanceOf(RuntimeException.class)
                .hasMessage("Dummy");
    }

    /**
     * Tests if multiple files can be downloaded and an {@code eachFile} action
     * is called for each of them
     * @throws Exception if anything goes wrong
     */
    @Test
    public void eachFileActionMultipleFiles() throws Exception {
        Download t = makeProjectAndTask();
        String u1 = wireMock.url(TEST_FILE_NAME);
        String u2 = wireMock.url(TEST_FILE_NAME2);
        t.src(Arrays.asList(u1, u2));

        File dst = newTempDir();
        t.dest(dst);

        AtomicInteger calls = new AtomicInteger(0);
        t.eachFile(details -> {
            if (details.getSourceURL().toString().equals(u1)) {
                assertThat(details.getName()).isEqualTo(TEST_FILE_NAME);
                calls.incrementAndGet();
            } else if (details.getSourceURL().toString().equals(u2)) {
                assertThat(details.getName()).isEqualTo(TEST_FILE_NAME2);
                calls.incrementAndGet();
            } else {
                fail("Unknown source URL: " + details.getSourceURL());
            }
        });
        execute(t);

        assertThat(new File(dst, TEST_FILE_NAME))
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS);
        assertThat(new File(dst, TEST_FILE_NAME2))
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS2);
        assertThat(calls.get()).isEqualTo(2);
    }

    /**
     * Tests if multiple files can be downloaded and an {@code eachFile} action
     * can be applied to rename them
     * @throws Exception if anything goes wrong
     */
    @Test
    public void eachFileActionMultipleFilesRename() throws Exception {
        Download t = makeProjectAndTask();
        String u1 = wireMock.url(TEST_FILE_NAME);
        String u2 = wireMock.url(TEST_FILE_NAME2);
        t.src(Arrays.asList(u1, u2));

        String nn1 = TEST_FILE_NAME + ".renamed";
        String nn2 = TEST_FILE_NAME2 + ".renamed";

        File dst = newTempDir();
        t.dest(dst);

        t.eachFile(details -> {
            if (details.getSourceURL().toString().equals(u1)) {
                assertThat(details.getName()).isEqualTo(TEST_FILE_NAME);
                details.setName(nn1);
            } else if (details.getSourceURL().toString().equals(u2)) {
                assertThat(details.getName()).isEqualTo(TEST_FILE_NAME2);
                details.setName(nn2);
            } else {
                fail("Unknown source URL: " + details.getSourceURL());
            }
        });
        execute(t);

        assertThat(new File(dst, TEST_FILE_NAME)).doesNotExist();
        assertThat(new File(dst, TEST_FILE_NAME2)).doesNotExist();
        assertThat(new File(dst, nn1))
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS);
        assertThat(new File(dst, nn2))
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS2);
    }

    /**
     * Tests if multiple files can be downloaded and an {@code eachFile} action
     * can be applied to change their relative path
     * @throws Exception if anything goes wrong
     */
    @Test
    public void eachFileActionMultipleFilesRelativePath() throws Exception {
        Download t = makeProjectAndTask();
        String u1 = wireMock.url(TEST_FILE_NAME);
        String u2 = wireMock.url(TEST_FILE_NAME2);
        t.src(Arrays.asList(u1, u2));

        String nn1 = "foo/" + TEST_FILE_NAME;
        String nn2 = "foo/" + TEST_FILE_NAME2;

        File dst = newTempDir();
        t.dest(dst);

        t.eachFile(details -> {
            if (details.getSourceURL().toString().equals(u1)) {
                assertThat(details.getName()).isEqualTo(TEST_FILE_NAME);
                assertThat(details.getPath()).isEqualTo(TEST_FILE_NAME);
                assertThat((Object)details.getRelativePath())
                        .isEqualTo(RelativePath.parse(true, TEST_FILE_NAME));
                // use setRelativePath()
                details.setRelativePath(RelativePath.parse(true, nn1));
                assertThat(details.getName()).isEqualTo(TEST_FILE_NAME);
                assertThat(details.getPath()).isEqualTo(nn1);
                assertThat((Object)details.getRelativePath())
                        .isEqualTo(RelativePath.parse(true, nn1));
            } else if (details.getSourceURL().toString().equals(u2)) {
                assertThat(details.getName()).isEqualTo(TEST_FILE_NAME2);
                assertThat(details.getPath()).isEqualTo(TEST_FILE_NAME2);
                assertThat((Object)details.getRelativePath())
                        .isEqualTo(RelativePath.parse(true, TEST_FILE_NAME2));
                // use setPath()
                details.setPath(nn2);
                assertThat(details.getName()).isEqualTo(TEST_FILE_NAME2);
                assertThat(details.getPath()).isEqualTo(nn2);
                assertThat((Object)details.getRelativePath())
                        .isEqualTo(RelativePath.parse(true, nn2));
            } else {
                fail("Unknown source URL: " + details.getSourceURL());
            }
        });
        execute(t);

        assertThat(new File(dst, TEST_FILE_NAME)).doesNotExist();
        assertThat(new File(dst, TEST_FILE_NAME2)).doesNotExist();
        assertThat(new File(dst, nn1))
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS);
        assertThat(new File(dst, nn2))
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS2);
    }

    /**
     * Tests if multiple files can be downloaded and an {@code eachFile} action
     * can be applied to change their relative path by setting their name
     * @throws Exception if anything goes wrong
     */
    @Test
    public void eachFileActionMultipleFilesRelativePathByName() throws Exception {
        Download t = makeProjectAndTask();
        String u1 = wireMock.url(TEST_FILE_NAME);
        String u2 = wireMock.url(TEST_FILE_NAME2);
        t.src(Arrays.asList(u1, u2));

        String nn1 = "foo/" + TEST_FILE_NAME;
        String nn2 = "foo/" + TEST_FILE_NAME2;

        File dst = newTempDir();
        t.dest(dst);

        t.eachFile(details -> {
            if (details.getSourceURL().toString().equals(u1)) {
                assertThat(details.getName()).isEqualTo(TEST_FILE_NAME);
                assertThat(details.getPath()).isEqualTo(TEST_FILE_NAME);
                assertThat((Object)details.getRelativePath())
                        .isEqualTo(RelativePath.parse(true, TEST_FILE_NAME));
                // use setName() instead of setRelativePath() or setPath()
                details.setName(nn1);
                assertThat(details.getName()).isEqualTo(nn1);
                assertThat(details.getPath()).isEqualTo(nn1);
                assertThat(details.getRelativePath().getPathString())
                        .isEqualTo(RelativePath.parse(true, nn1).getPathString());
            } else if (details.getSourceURL().toString().equals(u2)) {
                assertThat(details.getName()).isEqualTo(TEST_FILE_NAME2);
                assertThat(details.getPath()).isEqualTo(TEST_FILE_NAME2);
                assertThat((Object)details.getRelativePath())
                        .isEqualTo(RelativePath.parse(true, TEST_FILE_NAME2));
                // use setName() instead of setRelativePath() or setPath()
                details.setName(nn2);
                assertThat(details.getName()).isEqualTo(nn2);
                assertThat(details.getPath()).isEqualTo(nn2);
                assertThat(details.getRelativePath().getPathString())
                        .isEqualTo(RelativePath.parse(true, nn2).getPathString());
            } else {
                fail("Unknown source URL: " + details.getSourceURL());
            }
        });
        execute(t);

        assertThat(new File(dst, TEST_FILE_NAME)).doesNotExist();
        assertThat(new File(dst, TEST_FILE_NAME2)).doesNotExist();
        assertThat(new File(dst, nn1))
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS);
        assertThat(new File(dst, nn2))
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS2);
    }

    /**
     * Tests if multiple files can be downloaded and duplicate URLs can be
     * renamed by an {@code eachFile} action
     * @throws Exception if anything goes wrong
     */
    @Test
    public void eachFileActionMultipleFilesDuplicate() throws Exception {
        Download t = makeProjectAndTask();
        String u1 = wireMock.url(TEST_FILE_NAME);
        String u2 = wireMock.url(TEST_FILE_NAME2);
        String u3 = wireMock.url(TEST_FILE_NAME2);
        t.src(Arrays.asList(u1, u2, u3));

        File dst = newTempDir();
        t.dest(dst);

        AtomicInteger calls1 = new AtomicInteger(0);
        AtomicInteger calls2 = new AtomicInteger(0);
        t.eachFile(details -> {
            if (details.getSourceURL().toString().equals(u1)) {
                assertThat(details.getName()).isEqualTo(TEST_FILE_NAME);
                calls1.incrementAndGet();
                details.setName("1.txt");
            } else if (details.getSourceURL().toString().equals(u2)) {
                assertThat(details.getName()).isEqualTo(TEST_FILE_NAME2);
                if (calls2.incrementAndGet() == 1) {
                    details.setName("2.txt");
                } else {
                    details.setName("3.txt");
                }
            } else {
                fail("Unknown source URL: " + details.getSourceURL());
            }
        });
        execute(t);

        assertThat(calls1.get()).isEqualTo(1);
        assertThat(calls2.get()).isEqualTo(2);
        assertThat(new File(dst, TEST_FILE_NAME)).doesNotExist();
        assertThat(new File(dst, TEST_FILE_NAME2)).doesNotExist();
        assertThat(new File(dst, "1.txt"))
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS);
        assertThat(new File(dst, "2.txt"))
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS2);
        assertThat(new File(dst, "3.txt"))
                .usingCharset(StandardCharsets.UTF_8)
                .hasContent(CONTENTS2);
    }

    /**
     * Tests if an exception is thrown if an eachFile action returns duplicate
     * destinations.
     * @throws Exception if anything goes wrong
     */
    @Test
    public void eachFileActionDuplicateDests() throws Exception {
        Download t = makeProjectAndTask();
        String u1 = wireMock.url(TEST_FILE_NAME);
        String u2 = wireMock.url(TEST_FILE_NAME2);
        t.src(Arrays.asList(u1, u2));

        File dst = newTempDir();
        t.dest(dst);

        t.eachFile(details -> details.setName(TEST_FILE_NAME));
        assertThatThrownBy(() -> execute(t))
                .isInstanceOf(IllegalArgumentException.class)
                .hasMessage("Duplicate destination file '" + new File(dst, TEST_FILE_NAME) + "'");
    }
}


text:
[![Build Status](https://travis-ci.org/miya0001/pb-cli.svg?branch=master)](https://travis-ci.org/miya0001/pb-cli)
[![Gem Version](https://badge.fury.io/rb/pb-cli.svg)](https://badge.fury.io/rb/pb-cli)

A command line interface for Pushbullet.

https://www.pushbullet.com/

## Installation

Run:

```
$ gem install pb-cli
```

And then execute:

```
$ pb init <ACCESS-TOKEN>
```

To access the Pushbullet API you'll need an access token so the server knows who you are. You can get one from your [Account Settings](https://www.pushbullet.com/#settings/account) page.

## How to use

Send notification.

```
$ pb push create <MESSAGE> [--title <TITLE>]
```

Or send notification from STDIN.

```
$ ls -al | pb push create
```

See also `pb help`.

## Development

```
$ git clone git@github.com:miya0001/pb-cli.git
$ cd pb-cli
$ bundle install --path vendor/bundle
```

### Running automated tests

```
$ access_token=<ACCESS_TOKEN> bundle exec rspec
```

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/miya0001/pb-cli.

redpajama_set_name: RedPajamaGithub


text:
import { connect } from 'react-redux'
import PluginList from './PluginList'
import { addPlugin } from '../../dashboard'
import {
  pluginFilterSelector,
  changePluginFilter,
  filteredPluginsSeletor,
} from '../../store/filters'

const mapStateToProps = state => ({
  filter: pluginFilterSelector(state),
  plugins: filteredPluginsSeletor(state),
})

const mapDisaptchToProps = {
  changeFilter: changePluginFilter,
  addPlugin,
}

export default connect(
  mapStateToProps,
  mapDisaptchToProps,
)(PluginList)


text:
package org.apache.maven.api.services;

import static org.apache.maven.api.services.BaseRequest.nonNull;

import java.nio.file.Path;
import java.util.Optional;
import org.apache.maven.api.Session;
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.annotations.NotThreadSafe;
import org.apache.maven.api.annotations.Nullable;

public interface ToolchainsBuilderRequest {
    @Nonnull
    Session getSession();

    /**
     * Gets the global Toolchains path.
     *
     * @return the global Toolchains path or {@code null} if none
     */
    @Nonnull
    Optional<Path> getGlobalToolchainsPath();

    /**
     * Gets the global Toolchains source.
     *
     * @return the global Toolchains source or {@code null} if none
     */
    @Nonnull
    Optional<Source> getGlobalToolchainsSource();

    /**
     * Gets the user Toolchains path.
     *
     * @return the user Toolchains path or {@code null} if none
     */
    @Nonnull
    Optional<Path> getUserToolchainsPath();

    /**
     * Gets the user Toolchains source.
     *
     * @return the user Toolchains source or {@code null} if none
     */
    @Nonnull
    Optional<Source> getUserToolchainsSource();

    @Nonnull
    static ToolchainsBuilderRequest build(
            @Nonnull Session session, @Nonnull Source globalToolchainsSource, @Nonnull Source userToolchainsSource) {
        return builder()
                .session(nonNull(session, "session cannot be null"))
                .globalToolchainsSource(nonNull(globalToolchainsSource, "globalToolchainsSource cannot be null"))
                .userToolchainsSource(nonNull(userToolchainsSource, "userToolchainsSource cannot be null"))
                .build();
    }

    @Nonnull
    static ToolchainsBuilderRequest build(
            @Nonnull Session session, @Nonnull Path globalToolchainsPath, @Nonnull Path userToolchainsPath) {
        return builder()
                .session(nonNull(session, "session cannot be null"))
                .globalToolchainsPath(nonNull(globalToolchainsPath, "globalToolchainsPath cannot be null"))
                .userToolchainsPath(nonNull(userToolchainsPath, "userToolchainsPath cannot be null"))
                .build();
    }

    @Nonnull
    static ToolchainsBuilderRequestBuilder builder() {
        return new ToolchainsBuilderRequestBuilder();
    }

    @NotThreadSafe
    class ToolchainsBuilderRequestBuilder {
        Session session;
        Path globalToolchainsPath;
        Source globalToolchainsSource;
        Path userToolchainsPath;
        Source userToolchainsSource;

        public ToolchainsBuilderRequestBuilder session(Session session) {
            this.session = session;
            return this;
        }

        public ToolchainsBuilderRequestBuilder globalToolchainsPath(Path globalToolchainsPath) {
            this.globalToolchainsPath = globalToolchainsPath;
            return this;
        }

        public ToolchainsBuilderRequestBuilder globalToolchainsSource(Source globalToolchainsSource) {
            this.globalToolchainsSource = globalToolchainsSource;
            return this;
        }

        public ToolchainsBuilderRequestBuilder userToolchainsPath(Path userToolchainsPath) {
            this.userToolchainsPath = userToolchainsPath;
            return this;
        }

        public ToolchainsBuilderRequestBuilder userToolchainsSource(Source userToolchainsSource) {
            this.userToolchainsSource = userToolchainsSource;
            return this;
        }

        public ToolchainsBuilderRequest build() {
            return new ToolchainsBuilderRequestBuilder.DefaultToolchainsBuilderRequest(
                    session, globalToolchainsPath, globalToolchainsSource, userToolchainsPath, userToolchainsSource);
        }

        private static class DefaultToolchainsBuilderRequest extends BaseRequest implements ToolchainsBuilderRequest {
            private final Path globalToolchainsPath;
            private final Source globalToolchainsSource;
            private final Path userToolchainsPath;
            private final Source userToolchainsSource;

            @SuppressWarnings("checkstyle:ParameterNumber")
            DefaultToolchainsBuilderRequest(
                    @Nonnull Session session,
                    @Nullable Path globalToolchainsPath,
                    @Nullable Source globalToolchainsSource,
                    @Nullable Path userToolchainsPath,
                    @Nullable Source userToolchainsSource) {
                super(session);
                this.globalToolchainsPath = globalToolchainsPath;
                this.globalToolchainsSource = globalToolchainsSource;
                this.userToolchainsPath = userToolchainsPath;
                this.userToolchainsSource = userToolchainsSource;
            }

            @Nonnull
            @Override
            public Optional<Path> getGlobalToolchainsPath() {
                return Optional.ofNullable(globalToolchainsPath);
            }

            @Nonnull
            @Override
            public Optional<Source> getGlobalToolchainsSource() {
                return Optional.ofNullable(globalToolchainsSource);
            }

            @Nonnull
            @Override
            public Optional<Path> getUserToolchainsPath() {
                return Optional.ofNullable(userToolchainsPath);
            }

            @Nonnull
            @Override
            public Optional<Source> getUserToolchainsSource() {
                return Optional.ofNullable(userToolchainsSource);
            }
        }
    }
}


text:
<tool id="smrt_taxize" name="taxize" version="1.0.0">
    <description>smrt taxize description</description>

	<stdio>
      <exit_code range="1:" err_level="fatal" />
	</stdio>

    <command>
	  smrt taxize
        --root_taxa $input1
		--outfile $taxafile
    </command>
    <inputs>
        <param name="input1" type="text" label="root_taxon"/>
    </inputs>
    <outputs>
        <data name="taxafile" format="tabular" label="taxafile"/>
    </outputs>

<help>

.. class:: warningmark

**WARNING:** kkkk

-----

**What it does**

AAA

-----

**Example**

qqq

    </help>
</tool>


text:
require_relative '../../spec_helper'
require_testee

require 'tempfile'

describe RSA_AES_CBC do

    SEED = 'seed data'

    before :all do
        private_key_file = Tempfile.new( 'private_key.pem' )
        private_key = OpenSSL::PKey::RSA.generate( 1024 )
        private_key_file.write( private_key.to_pem )
        private_key_file.close

        public_key  = private_key.public_key
        public_key_file = Tempfile.new( 'public_key.pem' )
        public_key_file.write( public_key.to_pem )
        public_key_file.close

        @private_key_file_path = private_key_file.path
        @public_key_file_path = public_key_file.path

        @crypto = RSA_AES_CBC.new( @public_key_file_path, @private_key_file_path )
    end

    it 'should generate matching encrypted and decrypted data' do
        @crypto.decrypt( @crypto.encrypt( SEED ) ).should == SEED
    end

end


text:
<template>
	<require from='./card-element'></require>

		<card if.bind="pile.next" card.bind="pile.next"></card>

</template>


text:
@interface NSMutableData (AES)

- (NSData *)AES128EncryptWithKey:(NSString *)key;
- (NSData *)AES128DecryptWithKey:(NSString *)key;

@end


text:
package org.immutables.value.processor.meta;

import com.google.common.collect.Lists;
import org.immutables.value.processor.meta.Proto.Protoclass;

import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
import java.util.List;

final class FactoryMethodAttributesCollector {
  private final Protoclass protoclass;
  private final ValueType type;
  private final List<ValueAttribute> attributes = Lists.newArrayList();
  private final Styles styles;
  private final Reporter reporter;

  FactoryMethodAttributesCollector(Protoclass protoclass, ValueType type) {
    this.protoclass = protoclass;
    this.styles = protoclass.styles();
    this.type = type;
    this.reporter = protoclass.report();
  }

  void collect() {
    ExecutableElement factoryMethodElement = (ExecutableElement) protoclass.sourceElement();

    for (VariableElement parameter : factoryMethodElement.getParameters()) {
      TypeMirror returnType = parameter.asType();

      ValueAttribute attribute = new ValueAttribute();
      attribute.isGenerateAbstract = true;
      attribute.reporter = reporter;
      attribute.returnType = returnType;

      attribute.element = parameter;
      String parameterName = parameter.getSimpleName().toString();
      attribute.names = styles.forAccessorWithRaw(parameterName, parameterName);

      attribute.containingType = type;
      attributes.add(attribute);
    }

    for (ValueAttribute attribute : attributes) {
      attribute.initAndValidate();
    }

    type.attributes.addAll(attributes);
  }
}


text:
define(['underscore', 'views/addView'], function(_, AddView) {
    'use strict';
    var AddController = function(controller) {
        this.connection = controller;
        this.init();
    };

    _.extend(AddController.prototype, {

        init: function() {
            new AddView();
            this.bindEvents();
        },

        bindEvents: function() {
            // todo localStorage fallback
            var self = this;
            document.getElementById('add').addEventListener('click', function() {
                var cards = JSON.parse(localStorage.cards);
                var cardName = document.getElementById('card-name').value;
                // normally i'd create a collection with id's or something
                // where the one below should be registered and stuff like that
                var cardId = _.random(20, 99);
                var cardType = $('input#card-type').is(':checked') ? 'bug' : 'task';
                if (cardName) {
                    cards.push({
                        id: cardId,
                        name: cardName,
                        type: cardType,
                        status: 'toDo'
                    });
                    localStorage.cards = JSON.stringify(cards);
                    // TODO avoid reloading all the cards
                    self.connection.init();
                }

            }, false);
        }

    });

    return AddController;
});


text:
require File.expand_path("../../spec_helper", __FILE__)

module Redrack
  describe Session do

    it "faults on no connection" do
      expect { app(:redis_host => "nosuchserver") }.to raise_error { |e| [SocketError, Timeout::Error].should include(e.class) }
    end

    it "connects to existing server" do
      expect { app() }.to_not raise_error
    end

    it "passes options to Redis" do
      main_app = Redrack::Session::Middleware.new(Redrack::Session::RackApp.new, :redis_namespace => "test:rack:session")
      main_app.redis.namespace.should == "test:rack:session"
    end

    it "creates a new cookie" do
      get "/"
      rack_mock_session.cookie_jar["rack.session"].should be_a(String)
    end

    it "determines session from a cookie" do
      get("/add") { |r| r.body.should match /Session Counter: 1/ }
      get("/add") { |r| r.body.should match /Session Counter: 2/ }
      get("/add") { |r| r.body.should match /Session Counter: 3/ }
    end

    it "determines session only from a cookie by default" do
      get "/add"
      sid = rack_mock_session.cookie_jar["rack.session"]
      clear_cookies
      get("/add", "rack.session" => sid) { |r| r.body.should match /Session Counter: 1/ }
      sid = rack_mock_session.cookie_jar["rack.session"]
      clear_cookies
      get("/add", "rack.session" => sid) { |r| r.body.should match /Session Counter: 1/ }
    end

    it "determines session from params" do
      mock_session = Rack::MockSession.new(app(:cookie_only => false))
      session      = Rack::Test::Session.new(mock_session)
      session.get "/add"
      sid = mock_session.cookie_jar["rack.session"]
      session.clear_cookies
      session.get("/add", "rack.session" => sid) { |r| r.body.should match /Session Counter: 2/ }
      session.get("/add", "rack.session" => sid) { |r| r.body.should match /Session Counter: 3/ }
    end

    it "survives nonexistant cookies" do
      rack_mock_session.set_cookie("rack.session=badsessionid")
      get("/add") { |r| r.body.should match /Session Counter: 1/ }
      rack_mock_session.cookie_jar["rack.session"].should_not match /badsessionid/
    end

    it "maintains freshness" do
      mock_session = Rack::MockSession.new(app(:expire_after => 3))
      session      = Rack::Test::Session.new(mock_session)
      session.get("/add") { |r| r.body.should match /Session Counter: 1/ }
      sid = mock_session.cookie_jar["rack.session"]
      session.get("/add") { |r| r.body.should match /Session Counter: 2/ }
      mock_session.cookie_jar["rack.session"].should == sid
      puts "Sleeping to expire session..." if $DEBUG
      sleep 5
      session.get("/add") { |r| r.body.should match /Session Counter: 1/ }
      mock_session.cookie_jar["rack.session"].should_not == sid
    end

    it "does not send the same session id if it did not change" do
      get("/add") { |r| r.body.should match /Session Counter: 1/ }
      sid = rack_mock_session.cookie_jar["rack.session"]
      get("/add") do |r|
        r.headers["Set-Cookie"].should be_nil
        r.body.should match /Session Counter: 2/
      end
      get("/add") do |r|
        r.headers["Set-Cookie"].should be_nil
        r.body.should match /Session Counter: 3/
      end
    end

    it "deletes cookies with :drop option" do
      main_mock_session = Rack::MockSession.new(app())
      drop_mock_session = Rack::MockSession.new(drop_app())
      main_session      = Rack::Test::Session.new(main_mock_session)
      drop_session      = Rack::Test::Session.new(drop_mock_session)
      main_session.get("/add") { |r| r.body.should match /Session Counter: 1/ }
      sid = main_mock_session.cookie_jar["rack.session"]
      drop_mock_session.set_cookie("rack.session=#{sid}")
      drop_session.get("/add") do |r|
        r.header["Set-Cookie"].should be_nil
        r.body.should match /Session Counter: 2/
      end
      main_session.get("/add") { |r| r.body.should match /Session Counter: 1/ }
      main_mock_session.cookie_jar["rack.session"].should_not == sid
    end

    it "provides new session id with :renew option" do
      main_mock_session  = Rack::MockSession.new(app())
      renew_mock_session = Rack::MockSession.new(renew_app())
      main_session       = Rack::Test::Session.new(main_mock_session)
      renew_session      = Rack::Test::Session.new(renew_mock_session)
      main_session.get("/add")  { |r| r.body.should match /Session Counter: 1/ }
      old_sid = main_mock_session.cookie_jar["rack.session"]
      renew_mock_session.set_cookie("rack.session=#{old_sid}")
      renew_session.get("/add") { |r| r.body.should match /Session Counter: 2/ }
      new_sid = renew_mock_session.cookie_jar["rack.session"]
      new_sid.should_not == old_sid
      main_mock_session.clear_cookies
      main_mock_session.set_cookie("rack.session=#{new_sid}")
      main_session.get("/add") { |r| r.body.should match /Session Counter: 3/ }
      main_mock_session.clear_cookies
      main_mock_session.set_cookie("rack.session=#{old_sid}")
      main_session.get("/add") { |r| r.body.should match /Session Counter: 1/ }
    end

    it "omits cookie with :defer option" do
      mock_session = Rack::MockSession.new(defer_app())
      session      = Rack::Test::Session.new(mock_session)
      session.get("/add") { |r| r.body.should match /Session Counter: 1/ }
      mock_session.cookie_jar["rack.session"].should be_nil
    end

    it "updates deep hashes correctly" do
      main_app     = Redrack::Session::Middleware.new(Redrack::Session::RackApp.new)
      mock_session = Rack::MockSession.new(main_app)
      session      = Rack::Test::Session.new(mock_session)
      session.get("/set-deep-hash")
      sid    = mock_session.cookie_jar["rack.session"]
      first  = main_app.redis.get(sid)
      session.get("/mutate-deep-hash")
      first.should_not equal(main_app.redis.get(sid))
    end

    it "cleanly merges sessions when multithreaded" do
      mutex               = Mutex.new
      count               = 0
      main_app            = Redrack::Session::Middleware.new(Redrack::Session::RackApp.new)
      main_mock_session   = Rack::MockSession.new(main_app)
      thread_mock_session = Rack::MockSession.new(threaded_app())
      main_session        = Rack::Test::Session.new(main_mock_session)
      thread_session      = Rack::Test::Session.new(thread_mock_session)
      random_thread_count = lambda { rand(7).to_i + 5 }
      main_session.get("/add") { |r| r.body.should match /Session Counter: 1/ }
      sid = main_mock_session.cookie_jar["rack.session"]
      thread_mock_session.set_cookie("rack.session=#{sid}")

      # do several, multi-threaded requests...
      num_threads = random_thread_count.call
      threads     = (1..num_threads).map do |i|
        Thread.new(thread_session, thread_mock_session) do |session, mock|
          mutex.synchronize { count += 1 }
          session.get("/add", {}, "rack.multithreaded" => true)
          [mock.last_response.body, mock.cookie_jar["rack.session"]]
        end
      end
      sleep 1 until mutex.synchronize { count == num_threads }
      threads.each { |thread| sleep 1 until thread.stop? }
      requests = threads.reverse.map { |t| t.run.join.value }
      count = 2
      requests.each do |response|
        response.first.should match /Session Counter: #{count}/
        response.last.should == sid
        count += 1
      end

      # verify all our timestamps were written by the threaded_app
      session = Marshal.load(main_app.redis.get(sid))
      session.size.should       == num_threads + 1
      session["counter"].should == num_threads + 1

      # test multi-threaded session element deletion
      old_threads = num_threads
      num_threads = random_thread_count.call
      threads     = (1..num_threads).map do |i|
        Thread.new(main_session, main_mock_session) do |session, mock|
          session.get("/drop-counter", {}, "rack.multithreaded" => true)
          [mock.last_response.body, mock.cookie_jar["rack.session"]]
        end
      end
      requests = threads.reverse.map { |t| t.join.value }
      requests.each do |response|
        response.first.should match /Session Foo: bar/
        response.last.should == sid
      end
      session = Marshal.load(main_app.redis.get(sid))
      session.size.should       == old_threads + 1
      session["foo"].should     == "bar"
      session["counter"].should be_nil

    end

  end
end


text:
<link rel="stylesheet" href="webapp/dev/css/main.css">
<link rel="stylesheet" href="webapp/dev/css/bootstrap.css">
<link rel="stylesheet" href="webapp/dev/css/fontawesome.css">


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AspectCore.DependencyInjection;
using Xunit;

namespace AspectCore.Tests.Injector
{
    public class ManyEnumerableTest : InjectorTestBase
    {
        [Fact]
        public void Resolve_Many()
        {
            var many = ServiceResolver.ResolveMany<IService>();
            Assert.NotNull(many);
            Assert.Equal(3, many.Count());
            Assert.NotEqual(many, ServiceResolver.ResolveMany<IService>());
        }

        [Fact]
        public void Resolve_ManyEnumerable()
        {
            var many = ServiceResolver.Resolve<IManyEnumerable<IService>>();
            Assert.NotNull(many);
            Assert.Equal(3, many.Count());
            Assert.NotEqual(many, ServiceResolver.Resolve<IManyEnumerable<IService>>());
        }

        [Fact]
        public void Resolve_Not_Register()
        {
            var many = ServiceResolver.ResolveMany<Transient>();
            Assert.NotNull(many);
            Assert.Empty(many);
        }

        [Fact]
        public void Resolve_Enumerable_Lifetime()
        {
            var many = ServiceResolver.Resolve<IEnumerable<IService>>().ToArray();
            var many1 = ServiceResolver.Resolve<IEnumerable<IService>>().ToArray();
            Assert.NotEqual(many[0], many1[0]);
            Assert.Equal(many[1], many1[1]);
            Assert.Equal(many[2], many1[2]);
            using (var scope = ServiceResolver.CreateScope())
            {
                var many2 = scope.Resolve<IEnumerable<IService>>().ToArray();
                Assert.NotEqual(many[0], many2[0]);
                Assert.Equal(many[1], many2[1]);
                Assert.NotEqual(many[2], many2[2]);
            }
        }

        [Fact]
        public void Resolve_Many_Lifetime()
        {
            var many = ServiceResolver.ResolveMany<IService>().ToArray();
            var many1 = ServiceResolver.ResolveMany<IService>().ToArray();
            Assert.NotEqual(many[0], many1[0]);
            Assert.Equal(many[1], many1[1]);
            Assert.Equal(many[2], many1[2]);
            using (var scope = ServiceResolver.CreateScope())
            {
                var many2 = scope.Resolve<IEnumerable<IService>>().ToArray();
                Assert.NotEqual(many[0], many2[0]);
                Assert.Equal(many[1], many2[1]);
                Assert.NotEqual(many[2], many2[2]);
            }
        }

        protected override void ConfigureService(IServiceContext serviceContext)
        {
            serviceContext.Transients.AddType<IService, Transient>();
            serviceContext.Singletons.AddType<IService, Singleton>();
            serviceContext.Scopeds.AddType<IService, Scoped>();

            serviceContext.Singletons.AddDelegate<IManyEnumerable<IService>>(r => new ManyEnumerable<IService>(new IService[] { new Transient(), new Transient(), new Transient(), new Transient() }));

            base.ConfigureService(serviceContext);
        }
    }
}


text:
class NewsItem < ActiveRecord::Base
	validates :title, :body, presence: true
end


text:
using System;

namespace Digithought.Framework
{
	public static class Data
	{
		public static event LogDataHandler LogData;
		public static LogDataFilterHandler LogFilter;
		public static System.Text.RegularExpressions.Regex TopicMask = null;

		[System.Diagnostics.Conditional("FRAMEWORK_DATALOGGING")]
		public static void Log(DataHeader header, params object[] values)
		{
			LogTo(header, null, values);
		}

		public static void LogTo(DataHeader header, string fileName, params object[] values)
		{
			try
			{
				var filter = LogFilter;	// Capture
				var mask = TopicMask;	// Capture
				if
					(
						(filter == null || filter(header, values))
							&& (mask == null || mask.IsMatch(header.Topic))
					)
				{
					var handler = LogData;	// Capture
					if (handler != null)
						handler(header, fileName, values);
				}
			}
			catch (Exception e)
			{
				System.Diagnostics.Debug.WriteLine("Error attempting to log data: \r\n" + e.ToString());
				// Don't rethrow
			}
		}
	}

	public delegate void LogDataHandler(DataHeader header, string fileName, object[] values);

	public delegate bool LogDataFilterHandler(DataHeader header, object[] values);

	public class DataHeader
	{
		public DataHeader(string topic, params string[] valueDescriptions)
		{
			Topic = topic;
			ValueDescriptions = valueDescriptions;
		}

		public object Tag { get; set; }

		public string Topic { get; private set; }

		public string[] ValueDescriptions { get; private set; }
	}
}


text:
START_ATF_NAMESPACE
    namespace Detail
    {

        Info::_notice_move_limit_map_msg_zoclctor__notice_move_limit_map_msg_zocl2_ptr _notice_move_limit_map_msg_zoclctor__notice_move_limit_map_msg_zocl2_next(nullptr);
        Info::_notice_move_limit_map_msg_zoclctor__notice_move_limit_map_msg_zocl2_clbk _notice_move_limit_map_msg_zoclctor__notice_move_limit_map_msg_zocl2_user(nullptr);

        void _notice_move_limit_map_msg_zoclctor__notice_move_limit_map_msg_zocl2_wrapper(struct _notice_move_limit_map_msg_zocl* _this)
        {
           _notice_move_limit_map_msg_zoclctor__notice_move_limit_map_msg_zocl2_user(_this, _notice_move_limit_map_msg_zoclctor__notice_move_limit_map_msg_zocl2_next);
        };

        ::std::array<hook_record, 1> _notice_move_limit_map_msg_zocl_functions =
        {
            _hook_record {
                (LPVOID)0x1403a7100L,
                (LPVOID *)&_notice_move_limit_map_msg_zoclctor__notice_move_limit_map_msg_zocl2_user,
                (LPVOID *)&_notice_move_limit_map_msg_zoclctor__notice_move_limit_map_msg_zocl2_next,
                (LPVOID)cast_pointer_function(_notice_move_limit_map_msg_zoclctor__notice_move_limit_map_msg_zocl2_wrapper),
                (LPVOID)cast_pointer_function((void(_notice_move_limit_map_msg_zocl::*)())&_notice_move_limit_map_msg_zocl::ctor__notice_move_limit_map_msg_zocl)
            },
        };
    }; // end namespace Detail
END_ATF_NAMESPACE


text:
module.exports = function(grunt) {

  /**
   * Define "validate" and "analyze" tasks, and include required plugins.
   *
   * These tasks are used to ensure code quality.
   *
   * grunt validate
   *   Evaluate the quality of all custom code to make sure it is safe to push.
   *   Should be reasonably fast and display on the command-line.
   *
   * grunt analyze
   *   Deeper inspection & analyze of codebase, not done on every build.
   *   Produces reports for Jenkins. May be a long-running task.
   */
  grunt.loadNpmTasks('grunt-phplint');
  grunt.loadNpmTasks('grunt-phpcs');
  grunt.loadNpmTasks('grunt-phpmd');

  // Task set aliases are registered at the end of the file based on these values.
  var validate = [];
  var analyze = [];

  grunt.config('phplint', {
    all: [
      '<%= config.srcPaths.drupal %>/**/*.php',
      '<%= config.srcPaths.drupal %>/**/*.module',
      '<%= config.srcPaths.drupal %>/**/*.inc',
      '<%= config.srcPaths.drupal %>/**/*.install',
      '<%= config.srcPaths.drupal %>/**/*.profile',
      '!<%= config.srcPaths.drupal %>/**/*.features.*inc',
      '!<%= config.srcPaths.drupal %>/sites/**'
    ],
  });
  validate.push('phplint:all');

  if (grunt.config.get('config.phpcs') != undefined) {
    var phpcs = [
      '<%= config.srcPaths.drupal %>/**/*.php',
      '<%= config.srcPaths.drupal %>/**/*.module',
      '<%= config.srcPaths.drupal %>/**/*.inc',
      '<%= config.srcPaths.drupal %>/**/*.install',
      '<%= config.srcPaths.drupal %>/**/*.profile',
      '<%= config.srcPaths.drupal %>/**/*.css',
      '!<%= config.srcPaths.drupal %>/**/*.features.*inc',
      '!<%= config.srcPaths.drupal %>/sites/**'
    ];
    grunt.config('phpcs', {
      analyze: {
        dir: phpcs
      },
      drupal: {
        dir: phpcs
      },
      validate: {
        dir: phpcs,
        report: grunt.config.get('config.phpcs.validateReport') || 'full',
        reportFile: false,
      },
      full: {
        dir: phpcs,
        report: 'full',
        reportFile: false
      },
      summary: {
        dir: phpcs,
        report: 'summary',
        reportFile: false
      },
      gitblame: {
        dir: phpcs,
        report: 'gitblame',
        reportFile: false
      },
      options: {
        bin: '<%= config.phpcs.path %>',
        standard: '<%= config.phpcs.standard %>',
        extensions: 'php,install,module,inc,profile',
        ignoreExitCode: true,
        report: 'checkstyle',
        reportFile: '<%= config.buildPaths.reports %>/phpcs.xml'
      }
    });

    validate.push('phpcs:validate');
    analyze.push('phpcs:analyze');
  }

  if (grunt.config.get('config.phpmd') != undefined) {
    var phpmdConfig = grunt.config.get('config.phpmd.configPath') || 'phpmd.xml';
    grunt.config('phpmd', {
      custom: {
        dir: '<%= config.srcPaths.drupal %>/'
      },
      options: {
        bin: '<%= config.phpmd.path %>',
        rulesets: phpmdConfig,
        suffixes: "php,module,inc,install,profile",
        exclude: "<%= config.srcPaths.drupal %>/sites",
        reportFormat: 'xml',
        reportFile: '<%= config.buildPaths.reports %>/phpmd.xml'
      }
    });
    analyze.push('phpmd:custom');
  }

  grunt.registerTask('validate', validate);
  grunt.registerTask('analyze', analyze);

  grunt.config('help.validate', {
    group: 'Testing & Code Quality',
    description: 'Quick code health check for syntax errors and basic practices. (e.g., PHPCS w/ Drush Coder rules)'
  });
  grunt.config('help.analyze', {
    group: 'Testing & Code Quality',
    description: 'Static codebase analysis to detect problems. Outputs Jenkins-compatible reports. (e.g., PHPMD)'
  });

};


text:
package com.mobile.pos.iago.taskmanager.database.controllers;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.mobile.pos.iago.taskmanager.database.helper.SQLiteHelper;
import com.mobile.pos.iago.taskmanager.database.tables.TableTask;
import com.mobile.pos.iago.taskmanager.models.Task;
import com.mobile.pos.iago.taskmanager.views.activities.CreateTaskActivity;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by iago on 18/05/17.
 */

public class TaskDBController {

    private SQLiteDatabase db;
    private SQLiteHelper helper;

    public TaskDBController(Context context){
        helper = new SQLiteHelper(context);
    }

    /**
     * Create a new task
     * @param task the object reference of task
     * @return true if was saved on db, false otherwise
     */
    public boolean addNewTask(Task task){

        ContentValues values;
        long result;

        db = helper.getWritableDatabase();
        values = new ContentValues();
        values.put(TableTask.TASK_TITLE, task.getTaskTitle());
        values.put(TableTask.TASK_DESCRIPTION, task.getTaskDescription());
        values.put(TableTask.TASK_PRIORITY, task.getPriority().toString());
        values.put(TableTask.TASK_STATUS, task.getTaskStatus()? "1" : "0");

        result = db.insert(TableTask.TABLE_NAME, null, values);
        db.close();

        if (result == -1)
            return false;
        else
            return true;

    }

    /**
     * Get all task in database
     * @param withOnlyNotCompleted false case return must be all data
     * @return list of Tasks
     */
    public List<Task> getAllTask(boolean withOnlyNotCompleted){
        List<Task> tasks = new ArrayList<>();
        Cursor cursor;
        String[] fields =  {TableTask.ID,TableTask.TASK_TITLE,TableTask.TASK_DESCRIPTION,TableTask.TASK_PRIORITY, TableTask.TASK_STATUS, TableTask.TASK_DATE_FINISHED};
        db = helper.getReadableDatabase();
        if(withOnlyNotCompleted){
            cursor = db.query(TableTask.TABLE_NAME, fields, TableTask.TASK_STATUS+"=?", new String[] { "0" }, null, null, null, null);
        }else{
            cursor = db.query(TableTask.TABLE_NAME, fields, null, null, null, null, null, null);
        }

        if (cursor.moveToFirst()) {
            while (!cursor.isAfterLast()) {
                Task task = new Task();
                task.setId(cursor.getInt(cursor.getColumnIndex(TableTask.ID)));
                task.setTaskTitle(cursor.getString(cursor.getColumnIndex(TableTask.TASK_TITLE)));
                task.setTaskDescription(cursor.getString(cursor.getColumnIndex(TableTask.TASK_DESCRIPTION)));

                String priority = cursor.getString(cursor.getColumnIndex(TableTask.TASK_PRIORITY));

                if (priority.equals(CreateTaskActivity.Priority.High.toString())) {
                    task.setPriority(CreateTaskActivity.Priority.High);
                } else if (priority.equals(CreateTaskActivity.Priority.Medium.toString())) {
                    task.setPriority(CreateTaskActivity.Priority.Medium);
                } else {
                    task.setPriority(CreateTaskActivity.Priority.Low);
                }
                String taskStatus = cursor.getString(cursor.getColumnIndex(TableTask.TASK_STATUS));
                task.setTaskStatus( taskStatus.equals("1")? true: false);
                task.setTaskFinished(cursor.getString(cursor.getColumnIndex(TableTask.TASK_DATE_FINISHED)));
                tasks.add(task);
                cursor.moveToNext();
            }
        }
        db.close();
        return tasks;
    }

    /**
     * Change the task status
     * @param id
     * @param checked
     */
    public boolean setTaskStatus(int id, boolean checked){
        ContentValues values;
        String where;

        db = helper.getWritableDatabase();

        where = TableTask.ID + "=" + id;

        String date = new SimpleDateFormat("dd-MM-yyyy HH:mm").format(new Date());

        values = new ContentValues();
        values.put(TableTask.TASK_STATUS, checked ? "1": "0");
        values.put(TableTask.TASK_DATE_FINISHED, checked ? date : "");

        int result = db.update(TableTask.TABLE_NAME,values,where,null);
        db.close();
        if (result == -1) {
            return false;
        }
        else {
            return true;
        }
    }
}


text:
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */

/**
 * DNS Library for handling lookups and updates.
 *
 * PHP Version 5
 *
 * Copyright (c) 2010, Mike Pultz <mike@mikepultz.com>.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *
 *   * Neither the name of Mike Pultz nor the names of his contributors
 *     may be used to endorse or promote products derived from this
 *     software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @category  Networking
 * @package   Net_DNS2
 * @author    Mike Pultz <mike@mikepultz.com>
 * @copyright 2010 Mike Pultz <mike@mikepultz.com>
 * @license   http://www.opensource.org/licenses/bsd-license.php  BSD License
 * @version   SVN: $Id$
 * @link      http://pear.php.net/package/Net_DNS2
 * @since     File available since Release 0.6.0
 *
 */

/**
 * This is the base class for DNS Resource Records
 *
 * Each resource record type (defined in RR/*.php) extends this class for
 * base functionality.
 *
 * This class handles parsing and constructing the common parts of the DNS
 * resource records, while the RR specific functionality is handled in each
 * child class.
 *
 * DNS resource record format - RFC1035 section 4.1.3
 *
 *      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
 *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 *    |                                               |
 *    /                                               /
 *    /                      NAME                     /
 *    |                                               |
 *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 *    |                      TYPE                     |
 *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 *    |                     CLASS                     |
 *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 *    |                      TTL                      |
 *    |                                               |
 *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 *    |                   RDLENGTH                    |
 *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
 *    /                     RDATA                     /
 *    /                                               /
 *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 *
 * @category Networking
 * @package  Net_DNS2
 * @author   Mike Pultz <mike@mikepultz.com>
 * @license  http://www.opensource.org/licenses/bsd-license.php  BSD License
 * @link     http://pear.php.net/package/Net_DNS2
 *
 */
abstract class Net_DNS2_RR
{
    /*
     * The name of the resource record
     */
    public $name;

    /*
     * The resource record type
     */
    public $type;

    /*
     * The resouce record class
     */
    public $class;

    /*
     * The time to live for this resource record
     */
    public $ttl;

    /*
     * The length of the rdata field
     */
    public $rdlength;

    /*
     * The resource record specific data as a packed binary string
     */
    public $rdata;

    /**
     * abstract definition - method to return a RR as a string; not to
     * be confused with the __toString() magic method.
     *
     * @return string
     * @access protected
     *
     */
    abstract protected function rrToString();

    /**
     * abstract definition - parses a RR from a standard DNS config line
     *
     * @param array $rdata a string split line of values for the rdata
     *
     * @return boolean
     * @access protected
     *
     */
    abstract protected function rrFromString(array $rdata);

    /**
     * abstract definition - sets a Net_DNS2_RR from a Net_DNS2_Packet object
     *
     * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet to parse the RR from
     *
     * @return boolean
     * @access protected
     *
     */
    abstract protected function rrSet(Net_DNS2_Packet &$packet);

    /**
     * abstract definition - returns a binary packet DNS RR object
     *
     * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet use for
     *                                 compressed names
     *
     * @return mixed                   either returns a binary packed string or
     *                                 null on failure
     * @access protected
     *
     */
    abstract protected function rrGet(Net_DNS2_Packet &$packet);

    /**
     * Constructor - builds a new Net_DNS2_RR object
     *
     * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet or null to create
     *                                 an empty object
     * @param array           $rr      an array with RR parse values or null to
     *                                 create an empty object
     *
     * @throws Net_DNS2_Exception
     * @access public
     *
     */
    public function __construct(Net_DNS2_Packet &$packet = null, array $rr = null)
    {
        if ( (!is_null($packet)) && (!is_null($rr)) ) {

            if ($this->set($packet, $rr) == false) {

                throw new Net_DNS2_Exception(
                    'failed to generate resource record',
                    Net_DNS2_Lookups::E_RR_INVALID
                );
            }
        } else {

            $class = Net_DNS2_Lookups::$rr_types_class_to_id[get_class($this)];
            if (isset($class)) {

                $this->type = Net_DNS2_Lookups::$rr_types_by_id[$class];
            }

            $this->class    = 'IN';
            $this->ttl      = 86400;
        }
    }

    /**
     * magic __toString() method to return the Net_DNS2_RR object object as a string
     *
     * @return string
     * @access public
     *
     */
    public function __toString()
    {
        return $this->name . '. ' . $this->ttl . ' ' . $this->class .
            ' ' . $this->type . ' ' . $this->rrToString();
    }

    /**
     * return a formatted string; if a string has spaces in it, then return
     * it with double quotes around it, otherwise, return it as it was passed in.
     *
     * @param string $string the string to format
     *
     * @return string
     * @access protected
     *
     */
    protected function formatString($string)
    {
        return '"' . str_replace('"', '\"', trim($string, '"')) . '"';
    }

    /**
     * builds an array of strings from an array of chunks of text split by spaces
     *
     * @param array $chunks an array of chunks of text split by spaces
     *
     * @return array
     * @access protected
     *
     */
    protected function buildString(array $chunks)
    {
        $data = array();
        $c = 0;
        $in = false;

        foreach ($chunks as $r) {

            $r = trim($r);
            if (strlen($r) == 0) {
                continue;
            }

            if ( ($r[0] == '"')
                && ($r[strlen($r) - 1] == '"')
                && ($r[strlen($r) - 2] != '\\')
            ) {

                $data[$c] = $r;
                ++$c;
                $in = false;

            } else if ($r[0] == '"') {

                $data[$c] = $r;
                $in = true;

            } else if ( ($r[strlen($r) - 1] == '"')
                && ($r[strlen($r) - 2] != '\\')
            ) {

                $data[$c] .= ' ' . $r;
                ++$c;
                $in = false;

            } else {

                if ($in == true) {
                    $data[$c] .= ' ' . $r;
                } else {
                    $data[$c++] = $r;
                }
            }
        }

        foreach ($data as $index => $string) {

            $data[$index] = str_replace('\"', '"', trim($string, '"'));
        }

        return $data;
    }

    /**
     * builds a new Net_DNS2_RR object
     *
     * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet or null to create
     *                                 an empty object
     * @param array           $rr      an array with RR parse values or null to
     *                                 create an empty object
     *
     * @return boolean
     * @throws Net_DNS2_Exception
     * @access public
     *
     */
    public function set(Net_DNS2_Packet &$packet, array $rr)
    {
        $this->name     = $rr['name'];
        $this->type     = Net_DNS2_Lookups::$rr_types_by_id[$rr['type']];

        //
        // for RR OPT (41), the class value includes the requestors UDP payload size,
        // and not a class value
        //
        if ($this->type == 'OPT') {
            $this->class = $rr['class'];
        } else {
            $this->class = Net_DNS2_Lookups::$classes_by_id[$rr['class']];
        }

        $this->ttl      = $rr['ttl'];
        $this->rdlength = $rr['rdlength'];
        $this->rdata    = substr($packet->rdata, $packet->offset, $rr['rdlength']);

        return $this->rrSet($packet);
    }

    /**
     * returns a binary packed DNS RR object
     *
     * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet used for
     *                                 compressing names
     *
     * @return string
     * @throws Net_DNS2_Exception
     * @access public
     *
     */
    public function get(Net_DNS2_Packet &$packet)
    {
        $data  = '';
        $rdata = '';

        //
        // pack the name
        //
        $data = $packet->compress($this->name, $packet->offset);

        //
        // pack the main values
        //
        if ($this->type == 'OPT') {

            //
            // pre-build the TTL value
            //
            $this->preBuild();

            //
            // the class value is different for OPT types
            //
            $data .= pack(
                'nnN',
                Net_DNS2_Lookups::$rr_types_by_name[$this->type],
                $this->class,
                $this->ttl
            );
        } else {

            $data .= pack(
                'nnN',
                Net_DNS2_Lookups::$rr_types_by_name[$this->type],
                Net_DNS2_Lookups::$classes_by_name[$this->class],
                $this->ttl
            );
        }

        //
        // increase the offset, and allow for the rdlength
        //
        $packet->offset += 10;

        //
        // get the RR specific details
        //
        if ($this->rdlength != -1) {

            $rdata = $this->rrGet($packet);
        }

        //
        // add the RR
        //
        $data .= pack('n', strlen($rdata)) . $rdata;

        return $data;
    }

    /**
     * parses a binary packet, and returns the appropriate Net_DNS2_RR object,
     * based on the RR type of the binary content.
     *
     * @param Net_DNS2_Packet &$packet a Net_DNS2_Packet packet used for
     *                                 decompressing names
     *
     * @return mixed                   returns a new Net_DNS2_RR_* object for
     *                                 the given RR
     * @throws Net_DNS2_Exception
     * @access public
     *
     */
    public static function parse(Net_DNS2_Packet &$packet)
    {
        $object = array();

        //
        // expand the name
        //
        $object['name'] = $packet->expand($packet, $packet->offset);
        if (is_null($object['name'])) {

            throw new Net_DNS2_Exception(
                'failed to parse resource record: failed to expand name.',
                Net_DNS2_Lookups::E_PARSE_ERROR
            );
        }
        if ($packet->rdlength < ($packet->offset + 10)) {

            throw new Net_DNS2_Exception(
                'failed to parse resource record: packet too small.',
                Net_DNS2_Lookups::E_PARSE_ERROR
            );
        }

        //
        // unpack the RR details
        //
        $object['type']     = ord($packet->rdata[$packet->offset++]) << 8 |
                                ord($packet->rdata[$packet->offset++]);
        $object['class']    = ord($packet->rdata[$packet->offset++]) << 8 |
                                ord($packet->rdata[$packet->offset++]);

        $object['ttl']      = ord($packet->rdata[$packet->offset++]) << 24 |
                                ord($packet->rdata[$packet->offset++]) << 16 |
                                ord($packet->rdata[$packet->offset++]) << 8 |
                                ord($packet->rdata[$packet->offset++]);

        $object['rdlength'] = ord($packet->rdata[$packet->offset++]) << 8 |
                                ord($packet->rdata[$packet->offset++]);

        if ($packet->rdlength < ($packet->offset + $object['rdlength'])) {
            return null;
        }

        //
        // lookup the class to use
        //
        $o      = null;
        $class  = Net_DNS2_Lookups::$rr_types_id_to_class[$object['type']];

        if (isset($class)) {

            $o = new $class($packet, $object);
            if ($o) {

                $packet->offset += $object['rdlength'];
            }
        } else {

            throw new Net_DNS2_Exception(
                'un-implemented resource record type: ' . $object['type'],
                Net_DNS2_Lookups::E_RR_INVALID
            );
        }

        return $o;
    }

    /**
     * cleans up some RR data
     *
     * @param string $data the text string to clean
     *
     * @return string returns the cleaned string
     *
     * @access public
     *
     */
    public function cleanString($data)
    {
        return strtolower(rtrim($data, '.'));
    }

    /**
     * parses a standard RR format lines, as defined by rfc1035 (kinda)
     *
     * In our implementation, the domain *must* be specified- format must be
     *
     *        <name> [<ttl>] [<class>] <type> <rdata>
     * or
     *        <name> [<class>] [<ttl>] <type> <rdata>
     *
     * name, title, class and type are parsed by this function, rdata is passed
     * to the RR specific classes for parsing.
     *
     * @param string $line a standard DNS config line
     *
     * @return mixed       returns a new Net_DNS2_RR_* object for the given RR
     * @throws Net_DNS2_Exception
     * @access public
     *
     */
    public static function fromString($line)
    {
        if (strlen($line) == 0) {
            throw new Net_DNS2_Exception(
                'empty config line provided.',
                Net_DNS2_Lookups::E_PARSE_ERROR
            );
        }

        $name   = '';
        $type   = '';
        $class  = 'IN';
        $ttl    = 86400;

        //
        // split the line by spaces
        //
        $values = preg_split('/[\s]+/', $line);
        if (count($values) < 3) {

            throw new Net_DNS2_Exception(
                'failed to parse config: minimum of name, type and rdata required.',
                Net_DNS2_Lookups::E_PARSE_ERROR
            );
        }

        //
        // assume the first value is the name
        //
        $name = trim(strtolower(array_shift($values)), '.');

        //
        // The next value is either a TTL, Class or Type
        //
        foreach ($values as $value) {

            switch($value) {
            case is_numeric($value):

                $ttl = array_shift($values);
                break;

            //
            // PHP SUCKS!
            //
            case ($value === 0):
                $ttl = array_shift($values);
                break;

            case isset(Net_DNS2_Lookups::$classes_by_name[strtoupper($value)]):

                $class = strtoupper(array_shift($values));
                break;

            case isset(Net_DNS2_Lookups::$rr_types_by_name[strtoupper($value)]):

                $type = strtoupper(array_shift($values));
                break 2;
                break;
            default:

                throw new Net_DNS2_Exception(
                    'invalid config line provided: unknown file: ' . $value,
                    Net_DNS2_Lookups::E_PARSE_ERROR
                );
            }
        }

        //
        // lookup the class to use
        //
        $o = null;
        $class_name = Net_DNS2_Lookups::$rr_types_id_to_class[
            Net_DNS2_Lookups::$rr_types_by_name[$type]
        ];

        if (isset($class_name)) {

            $o = new $class_name;
            if (!is_null($o)) {

                //
                // set the parsed values
                //
                $o->name    = $name;
                $o->class   = $class;
                $o->ttl     = $ttl;

                //
                // parse the rdata
                //
                if ($o->rrFromString($values) === false) {

                    throw new Net_DNS2_Exception(
                        'failed to parse rdata for config: ' . $line,
                        Net_DNS2_Lookups::E_PARSE_ERROR
                    );
                }

            } else {

                throw new Net_DNS2_Exception(
                    'failed to create new RR record for type: ' . $type,
                    Net_DNS2_Lookups::E_RR_INVALID
                );
            }

        } else {

            throw new Net_DNS2_Exception(
                'un-implemented resource record type: '. $type,
                Net_DNS2_Lookups::E_RR_INVALID
            );
        }

        return $o;
    }
}

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * c-hanging-comment-ender-p: nil
 * End:
 */
?>


text:
from io import BytesIO

from construct.core import Adapter, AdaptationError, Pass
from construct.lib import int_to_bin, bin_to_int, swap_bytes
from construct.lib import FlagsContainer, HexString

#===============================================================================
# exceptions
#===============================================================================
class BitIntegerError(AdaptationError):
    pass
class MappingError(AdaptationError):
    pass
class ValidationError(AdaptationError):
    pass

#===============================================================================
# adapters
#===============================================================================
class BitIntegerAdapter(Adapter):
    """
    Adapter for bit-integers (converts bitstrings to integers, and vice versa).
    See BitField.

    :param subcon: the subcon to adapt
    :param width: the size of the subcon, in bits
    :param swapped: whether to swap byte order (little endian/big endian).
                    default is False (big endian)
    :param signed: whether the value is signed (two's complement). the default
                   is False (unsigned)
    :param bytesize: number of bits per byte, used for byte-swapping (if swapped).
                     default is 8.
    """
    __slots__ = ["width", "swapped", "signed", "bytesize"]
    def __init__(self, subcon, width, swapped = False, signed = False,
                 bytesize = 8):
        super(BitIntegerAdapter, self).__init__(subcon)
        self.width = width
        self.swapped = swapped
        self.signed = signed
        self.bytesize = bytesize
    def _encode(self, obj, context):
        if obj < 0 and not self.signed:
            raise BitIntegerError("object is negative, but field is not signed",
                obj)
        obj2 = int_to_bin(obj, width = self.width(context) if callable(self.width) else self.width)
        if self.swapped:
            obj2 = swap_bytes(obj2, bytesize = self.bytesize)
        return obj2
    def _decode(self, obj, context):
        if self.swapped:
            obj = swap_bytes(obj, bytesize = self.bytesize)
        return bin_to_int(obj, signed = self.signed)

class MappingAdapter(Adapter):
    """
    Adapter that maps objects to other objects.
    See SymmetricMapping and Enum.

    :param subcon: the subcon to map
    :param decoding: the decoding (parsing) mapping (a dict)
    :param encoding: the encoding (building) mapping (a dict)
    :param decdefault: the default return value when the object is not found
                       in the decoding mapping. if no object is given, an exception is raised.
                       if ``Pass`` is used, the unmapped object will be passed as-is
    :param encdefault: the default return value when the object is not found
                       in the encoding mapping. if no object is given, an exception is raised.
                       if ``Pass`` is used, the unmapped object will be passed as-is
    """
    __slots__ = ["encoding", "decoding", "encdefault", "decdefault"]
    def __init__(self, subcon, decoding, encoding,
                 decdefault = NotImplemented, encdefault = NotImplemented):
        super(MappingAdapter, self).__init__(subcon)
        self.decoding = decoding
        self.encoding = encoding
        self.decdefault = decdefault
        self.encdefault = encdefault
    def _encode(self, obj, context):
        try:
            return self.encoding[obj]
        except (KeyError, TypeError):
            if self.encdefault is NotImplemented:
                raise MappingError("no encoding mapping for %r [%s]" % (
                    obj, self.subcon.name))
            if self.encdefault is Pass:
                return obj
            return self.encdefault
    def _decode(self, obj, context):
        try:
            return self.decoding[obj]
        except (KeyError, TypeError):
            if self.decdefault is NotImplemented:
                raise MappingError("no decoding mapping for %r [%s]" % (
                    obj, self.subcon.name))
            if self.decdefault is Pass:
                return obj
            return self.decdefault

class FlagsAdapter(Adapter):
    """
    Adapter for flag fields. Each flag is extracted from the number, resulting
    in a FlagsContainer object. Not intended for direct usage. See FlagsEnum.

    :param subcon: the subcon to extract
    :param flags: a dictionary mapping flag-names to their value
    """
    __slots__ = ["flags"]
    def __init__(self, subcon, flags):
        super(FlagsAdapter, self).__init__(subcon)
        self.flags = flags
    def _encode(self, obj, context):
        flags = 0
        try:
            for name, value in obj.items():
                if value:
                    flags |= self.flags[name]
        except AttributeError:
            raise MappingError("not a mapping type: %r" % (obj,))
        except KeyError:
            raise MappingError("unknown flag: %s" % name)
        return flags
    def _decode(self, obj, context):
        obj2 = FlagsContainer()
        for name, value in self.flags.items():
            obj2[name] = bool(obj & value)
        return obj2

class StringAdapter(Adapter):
    """
    Adapter for strings. Converts a sequence of characters into a python
    string, and optionally handles character encoding. See String.

    :param subcon: the subcon to convert
    :param encoding: the character encoding name (e.g., "utf8"), or None to
                     return raw bytes (usually 8-bit ASCII).
    """
    __slots__ = ["encoding"]
    def __init__(self, subcon, encoding = None):
        super(StringAdapter, self).__init__(subcon)
        self.encoding = encoding
    def _encode(self, obj, context):
        if self.encoding:
            if isinstance(self.encoding, str):
                obj = obj.encode(self.encoding)
            else:
                obj = self.encoding.encode(obj)
        return obj
    def _decode(self, obj, context):
        if not isinstance(obj, bytes):
            obj = b"".join(obj)
        if self.encoding:
            if isinstance(self.encoding, str):
                obj = obj.decode(self.encoding)
            else:
                obj = self.encoding.decode(obj)
        return obj

class PaddedStringAdapter(Adapter):
    r"""
    Adapter for padded strings. See String.

    :param subcon: the subcon to adapt
    :param padchar: the padding character. default is "\x00".
    :param paddir: the direction where padding is placed ("right", "left", or
                   "center"). the default is "right".
    :param trimdir: the direction where trimming will take place ("right" or
                    "left"). the default is "right". trimming is only meaningful for
                    building, when the given string is too long.
    """
    __slots__ = ["padchar", "paddir", "trimdir"]
    def __init__(self, subcon, padchar = b"\x00", paddir = "right", trimdir = "right"):
        if paddir not in ("right", "left", "center"):
            raise ValueError("paddir must be 'right', 'left' or 'center'", paddir)
        if trimdir not in ("right", "left"):
            raise ValueError("trimdir must be 'right' or 'left'", trimdir)
        super(PaddedStringAdapter, self).__init__(subcon)
        self.padchar = padchar
        self.paddir = paddir
        self.trimdir = trimdir
    def _decode(self, obj, context):
        if self.paddir == "right":
            obj = obj.rstrip(self.padchar)
        elif self.paddir == "left":
            obj = obj.lstrip(self.padchar)
        else:
            obj = obj.strip(self.padchar)
        return obj
    def _encode(self, obj, context):
        size = self._sizeof(context)
        if self.paddir == "right":
            obj = obj.ljust(size, self.padchar)
        elif self.paddir == "left":
            obj = obj.rjust(size, self.padchar)
        else:
            obj = obj.center(size, self.padchar)
        if len(obj) > size:
            if self.trimdir == "right":
                obj = obj[:size]
            else:
                obj = obj[-size:]
        return obj

class CStringAdapter(StringAdapter):
    r"""
    Adapter for C-style strings (strings terminated by a terminator char).

    :param subcon: the subcon to convert
    :param terminators: a sequence of terminator chars. default is "\x00".
    :param encoding: the character encoding to use (e.g., "utf8"), or None to return raw-bytes.
                     the terminator characters are not affected by the encoding.
    """
    __slots__ = ["terminators"]
    def __init__(self, subcon, terminators = b"\x00", encoding = None):
        super(CStringAdapter, self).__init__(subcon, encoding = encoding)
        self.terminators = terminators
    def _encode(self, obj, context):
        return StringAdapter._encode(self, obj, context) + self.terminators[0:1]
    def _decode(self, obj, context):
        return StringAdapter._decode(self, b''.join(obj[:-1]), context)

class TunnelAdapter(Adapter):
    """
    Adapter for tunneling (as in protocol tunneling). A tunnel is construct
    nested upon another (layering). For parsing, the lower layer first parses
    the data (note: it must return a string!), then the upper layer is called
    to parse that data (bottom-up). For building it works in a top-down manner;
    first the upper layer builds the data, then the lower layer takes it and
    writes it to the stream.

    :param subcon: the lower layer subcon
    :param inner_subcon: the upper layer (tunneled/nested) subcon

    Example::

        # a pascal string containing compressed data (zlib encoding), so first
        # the string is read, decompressed, and finally re-parsed as an array
        # of UBInt16
        TunnelAdapter(
            PascalString("data", encoding = "zlib"),
            GreedyRange(UBInt16("elements"))
        )

    """
    __slots__ = ["inner_subcon"]
    def __init__(self, subcon, inner_subcon):
        super(TunnelAdapter, self).__init__(subcon)
        self.inner_subcon = inner_subcon
    def _decode(self, obj, context):
        return self.inner_subcon._parse(BytesIO(obj), context)
    def _encode(self, obj, context):
        stream = BytesIO()
        self.inner_subcon._build(obj, stream, context)
        return stream.getvalue()

class ExprAdapter(Adapter):
    """
    A generic adapter that accepts 'encoder' and 'decoder' as parameters. You
    can use ExprAdapter instead of writing a full-blown class when only a
    simple expression is needed.

    :param subcon: the subcon to adapt
    :param encoder: a function that takes (obj, context) and returns an encoded version of obj
    :param decoder: a function that takes (obj, context) and returns an decoded version of obj

    Example::

        ExprAdapter(UBInt8("foo"),
            encoder = lambda obj, ctx: obj / 4,
            decoder = lambda obj, ctx: obj * 4,
        )
    """
    __slots__ = ["_encode", "_decode"]
    def __init__(self, subcon, encoder, decoder):
        super(ExprAdapter, self).__init__(subcon)
        self._encode = encoder
        self._decode = decoder

class HexDumpAdapter(Adapter):
    """
    Adapter for hex-dumping strings. It returns a HexString, which is a string
    """
    __slots__ = ["linesize"]
    def __init__(self, subcon, linesize = 16):
        super(HexDumpAdapter, self).__init__(subcon)
        self.linesize = linesize
    def _encode(self, obj, context):
        return obj
    def _decode(self, obj, context):
        return HexString(obj, linesize = self.linesize)

class SlicingAdapter(Adapter):
    """
    Adapter for slicing a list (getting a slice from that list)

    :param subcon: the subcon to slice
    :param start: start index
    :param stop: stop index (or None for up-to-end)
    :param step: step (or None for every element)
    """
    __slots__ = ["start", "stop", "step"]
    def __init__(self, subcon, start, stop = None):
        super(SlicingAdapter, self).__init__(subcon)
        self.start = start
        self.stop = stop
    def _encode(self, obj, context):
        if self.start is None:
            return obj
        return [None] * self.start + obj
    def _decode(self, obj, context):
        return obj[self.start:self.stop]

class IndexingAdapter(Adapter):
    """
    Adapter for indexing a list (getting a single item from that list)

    :param subcon: the subcon to index
    :param index: the index of the list to get
    """
    __slots__ = ["index"]
    def __init__(self, subcon, index):
        super(IndexingAdapter, self).__init__(subcon)
        if type(index) is not int:
            raise TypeError("index must be an integer", type(index))
        self.index = index
    def _encode(self, obj, context):
        return [None] * self.index + [obj]
    def _decode(self, obj, context):
        return obj[self.index]

#===============================================================================
# validators
#===============================================================================
class Validator(Adapter):
    """
    Abstract class: validates a condition on the encoded/decoded object.
    Override _validate(obj, context) in deriving classes.

    :param subcon: the subcon to validate
    """
    __slots__ = []
    def _decode(self, obj, context):
        if not self._validate(obj, context):
            raise ValidationError("invalid object", obj)
        return obj
    def _encode(self, obj, context):
        return self._decode(obj, context)
    def _validate(self, obj, context):
        raise NotImplementedError()

class OneOf(Validator):
    """
    Validates that the object is one of the listed values.

    :param subcon: object to validate
    :param valids: a set of valid values

    Example::

        >>> OneOf(UBInt8("foo"), [4,5,6,7]).parse("\\x05")
        5
        >>> OneOf(UBInt8("foo"), [4,5,6,7]).parse("\\x08")
        Traceback (most recent call last):
            ...
        construct.core.ValidationError: ('invalid object', 8)
        >>>
        >>> OneOf(UBInt8("foo"), [4,5,6,7]).build(5)
        '\\x05'
        >>> OneOf(UBInt8("foo"), [4,5,6,7]).build(9)
        Traceback (most recent call last):
            ...
        construct.core.ValidationError: ('invalid object', 9)
    """
    __slots__ = ["valids"]
    def __init__(self, subcon, valids):
        super(OneOf, self).__init__(subcon)
        self.valids = valids
    def _validate(self, obj, context):
        return obj in self.valids

class NoneOf(Validator):
    """
    Validates that the object is none of the listed values.

    :param subcon: object to validate
    :param invalids: a set of invalid values

    Example::

        >>> NoneOf(UBInt8("foo"), [4,5,6,7]).parse("\\x08")
        8
        >>> NoneOf(UBInt8("foo"), [4,5,6,7]).parse("\\x06")
        Traceback (most recent call last):
            ...
        construct.core.ValidationError: ('invalid object', 6)
    """
    __slots__ = ["invalids"]
    def __init__(self, subcon, invalids):
        super(NoneOf, self).__init__(subcon)
        self.invalids = invalids
    def _validate(self, obj, context):
        return obj not in self.invalids


text:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- From: file:/Users/Andreas/Projekte/MobileBattery/Android/app/build/intermediates/exploded-aar/com.android.support/appcompat-v7/22.0.0/res/values-w720dp-v13/values.xml -->
    <eat-comment/>
    <bool name="abc_action_bar_expanded_action_views_exclusive">false</bool>
</resources>