text:
// Copyright 2015 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.devtools.build.lib.skyframe;

import static com.google.common.truth.Truth.assertThat;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.events.NullEventHandler;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.PackageFactory.EnvironmentExtension;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.WorkspaceFileValue;
import com.google.devtools.build.lib.packages.WorkspaceFileValue.WorkspaceFileKey;
import com.google.devtools.build.lib.packages.semantics.BuildLanguageOptions;
import com.google.devtools.build.lib.rules.repository.ManagedDirectoriesKnowledgeImpl;
import com.google.devtools.build.lib.rules.repository.ManagedDirectoriesKnowledgeImpl.ManagedDirectoriesListener;
import com.google.devtools.build.lib.skyframe.util.SkyframeExecutorTestUtils;
import com.google.devtools.build.lib.vfs.ModifiedFileSet;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Root;
import com.google.devtools.build.lib.vfs.RootedPath;
import com.google.devtools.build.skyframe.EvaluationResult;
import com.google.devtools.build.skyframe.Injectable;
import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import javax.annotation.Nullable;
import net.starlark.java.eval.StarlarkSemantics;
import net.starlark.java.syntax.ParserInput;
import net.starlark.java.syntax.StarlarkFile;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Test for {@link WorkspaceFileFunction}.
 */
@RunWith(JUnit4.class)
public class WorkspaceFileFunctionTest extends BuildViewTestCase {

  private TestManagedDirectoriesKnowledge testManagedDirectoriesKnowledge;

  @Override
  protected ManagedDirectoriesKnowledge getManagedDirectoriesKnowledge() {
    testManagedDirectoriesKnowledge = new TestManagedDirectoriesKnowledge();
    return testManagedDirectoriesKnowledge;
  }

  @Override
  protected Iterable<EnvironmentExtension> getEnvironmentExtensions() {
    return ImmutableList.of();
  }

  private static Label getLabelMapping(Package pkg, String name) throws NoSuchTargetException {
    return (Label) ((Rule) pkg.getTarget(name)).getAttr("actual");
  }

  private RootedPath createWorkspaceFile(String... contents) throws IOException {
    Path workspacePath = scratch.overwriteFile("WORKSPACE", contents);
    return RootedPath.toRootedPath(
        Root.fromPath(workspacePath.getParentDirectory()),
        PathFragment.create(workspacePath.getBaseName()));
  }

  // Dummy hamcrest matcher that match the function name of a skykey
  static class SkyKeyMatchers extends BaseMatcher<SkyKey> {
    private final SkyFunctionName functionName;

    public SkyKeyMatchers(SkyFunctionName functionName) {
      this.functionName = functionName;
    }
    @Override
    public boolean matches(Object item) {
      if (item instanceof SkyKey) {
        return ((SkyKey) item).functionName().equals(functionName);
      }
      return false;
    }

    @Override
    public void describeTo(Description description) {}
  }

  private <T extends SkyValue> EvaluationResult<T> eval(SkyKey key) throws InterruptedException {
    getSkyframeExecutor()
        .invalidateFilesUnderPathForTesting(
            reporter,
            ModifiedFileSet.builder().modify(PathFragment.create("WORKSPACE")).build(),
            Root.fromPath(rootDirectory));
    return SkyframeExecutorTestUtils.evaluate(
        getSkyframeExecutor(), key, /*keepGoing=*/ false, reporter);
  }

  @Test
  public void testLoadToChunkMapSimple() throws Exception {
    scratch.file("a.bzl", "a = 'a'");
    scratch.file("b.bzl", "b = 'b'");
    scratch.file("BUILD", "");
    RootedPath workspace =
        createWorkspaceFile(
            "workspace(name = 'good')",
            "load('//:a.bzl', 'a')",
            "x = 1  #for chunk break",
            "load('//:b.bzl', 'b')");
    SkyKey key1 = WorkspaceFileValue.key(workspace, 1);
    EvaluationResult<WorkspaceFileValue> result1 = eval(key1);
    WorkspaceFileValue value1 = result1.get(key1);
    assertThat(value1.getLoadToChunkMap()).containsEntry("//:a.bzl", 1);

    SkyKey key2 = WorkspaceFileValue.key(workspace, 2);
    EvaluationResult<WorkspaceFileValue> result2 = eval(key2);
    WorkspaceFileValue value2 = result2.get(key2);
    assertThat(value2.getLoadToChunkMap()).containsEntry("//:a.bzl", 1);
    assertThat(value2.getLoadToChunkMap()).containsEntry("//:b.bzl", 2);
  }

  @Test
  public void testLoadToChunkMapDoesNotOverrideDuplicate() throws Exception {
    scratch.file("a.bzl", "a = 'a'");
    scratch.file("BUILD", "");
    RootedPath workspace =
        createWorkspaceFile(
            "workspace(name = 'good')",
            "load('//:a.bzl', 'a')",
            "x = 1  #for chunk break",
            "load('//:a.bzl', 'a')");
    SkyKey key1 = WorkspaceFileValue.key(workspace, 1);
    EvaluationResult<WorkspaceFileValue> result1 = eval(key1);
    WorkspaceFileValue value1 = result1.get(key1);
    assertThat(value1.getLoadToChunkMap()).containsEntry("//:a.bzl", 1);

    SkyKey key2 = WorkspaceFileValue.key(workspace, 2);
    EvaluationResult<WorkspaceFileValue> result2 = eval(key2);
    WorkspaceFileValue value2 = result2.get(key2);
    assertThat(value2.getLoadToChunkMap()).containsEntry("//:a.bzl", 1);
    assertThat(value2.getLoadToChunkMap()).doesNotContainEntry("//:a.bzl", 2);
  }

  @Test
  public void testRepositoryMappingInChunks() throws Exception {
    scratch.file("b.bzl", "b = 'b'");
    scratch.file("BUILD", "");
    RootedPath workspace =
        createWorkspaceFile(
            "workspace(name = 'good')",
            "local_repository(name = 'a', path = '../a', repo_mapping = {'@x' : '@y'})",
            "load('//:b.bzl', 'b')",
            "local_repository(name = 'b', path = '../b', repo_mapping = {'@x' : '@y'})");
    RepositoryName a = RepositoryName.create("@a");
    RepositoryName b = RepositoryName.create("@b");
    RepositoryName x = RepositoryName.create("@x");
    RepositoryName y = RepositoryName.create("@y");
    RepositoryName good = RepositoryName.create("@good");
    RepositoryName main = RepositoryName.create("@");

    SkyKey key0 = WorkspaceFileValue.key(workspace, 0);
    EvaluationResult<WorkspaceFileValue> result0 = eval(key0);
    WorkspaceFileValue value0 = result0.get(key0);
    assertThat(value0.getRepositoryMapping()).containsEntry(a, ImmutableMap.of(x, y, good, main));

    SkyKey key1 = WorkspaceFileValue.key(workspace, 1);
    EvaluationResult<WorkspaceFileValue> result1 = eval(key1);
    WorkspaceFileValue value1 = result1.get(key1);
    assertThat(value1.getRepositoryMapping()).containsEntry(a, ImmutableMap.of(x, y, good, main));
    assertThat(value1.getRepositoryMapping()).containsEntry(b, ImmutableMap.of(x, y, good, main));
  }

  @Test
  public void setTestManagedDirectoriesKnowledge() throws Exception {
    StarlarkSemantics semantics = getStarlarkSemantics();
    Injectable injectable = getSkyframeExecutor().injectable();
    try {
      TestManagedDirectoriesListener listener = new TestManagedDirectoriesListener();
      ManagedDirectoriesKnowledgeImpl knowledge = new ManagedDirectoriesKnowledgeImpl(listener);

      RepositoryName one = RepositoryName.create("@repo1");
      RepositoryName two = RepositoryName.create("@repo2");
      RepositoryName three = RepositoryName.create("@repo3");

      PathFragment pf1 = PathFragment.create("dir1");
      PathFragment pf2 = PathFragment.create("dir2");
      PathFragment pf3 = PathFragment.create("dir3");

      assertThat(knowledge.getManagedDirectories(one)).isEmpty();
      assertThat(knowledge.getOwnerRepository(pf1)).isNull();

      WorkspaceFileValue workspaceFileValue = createWorkspaceFileValueForTest();
      boolean isChanged = knowledge.workspaceHeaderReloaded(null, workspaceFileValue);

      assertThat(isChanged).isTrue();
      assertThat(listener.getRepositoryNames()).containsExactly(one, two);

      assertThat(knowledge.getManagedDirectories(one)).containsExactly(pf1, pf2);
      assertThat(knowledge.getManagedDirectories(two)).containsExactly(pf3);
      assertThat(knowledge.getManagedDirectories(three)).isEmpty();

      assertThat(knowledge.getOwnerRepository(pf1)).isEqualTo(one);
      assertThat(knowledge.getOwnerRepository(pf2)).isEqualTo(one);
      assertThat(knowledge.getOwnerRepository(pf3)).isEqualTo(two);

      // Nothing changed, let's test the behavior.
      listener.reset();
      isChanged = knowledge.workspaceHeaderReloaded(workspaceFileValue, workspaceFileValue);
      assertThat(isChanged).isFalse();
      assertThat(listener.getRepositoryNames()).containsExactly(one, two);

      assertThat(knowledge.getManagedDirectories(one)).containsExactly(pf1, pf2);
      assertThat(knowledge.getManagedDirectories(two)).containsExactly(pf3);
      assertThat(knowledge.getManagedDirectories(three)).isEmpty();

      assertThat(knowledge.getOwnerRepository(pf1)).isEqualTo(one);
      assertThat(knowledge.getOwnerRepository(pf2)).isEqualTo(one);
      assertThat(knowledge.getOwnerRepository(pf3)).isEqualTo(two);
    } finally {
      PrecomputedValue.STARLARK_SEMANTICS.set(injectable, semantics);
    }
  }

  @Test
  public void testManagedDirectories() throws Exception {
    StarlarkSemantics semantics = getStarlarkSemantics();
    Injectable injectable = getSkyframeExecutor().injectable();
    try {
      createWorkspaceFileValueForTest();

      // Test intentionally introduces errors.
      reporter.removeHandler(failFastHandler);

      assertManagedDirectoriesParsingError(
          "{'@repo1': 'dir1', '@repo2': ['dir3']}",
          "managed_directories attribute value should be of the type attr.string_list_dict(),"
              + " mapping repository name to the list of managed directories.");

      assertManagedDirectoriesParsingError(
          "{'@repo1': ['dir1'], '@repo2': ['dir1']}",
          "managed_directories attribute should not contain multiple (or duplicate) repository"
              + " mappings for the same directory ('dir1').");

      assertManagedDirectoriesParsingError(
          "{'@repo1': ['']}", "Expected managed directory path to be non-empty string.");
      assertManagedDirectoriesParsingError(
          "{'@repo1': ['/abc']}",
          "Expected managed directory path ('/abc') to be relative to the workspace root.");
      assertManagedDirectoriesParsingError(
          "{'@repo1': ['../abc']}",
          "Expected managed directory path ('../abc') to be under the workspace root.");
      assertManagedDirectoriesParsingError(
          "{'@repo1': ['a/b', 'a/b']}",
          "managed_directories attribute should not contain multiple (or duplicate)"
              + " repository mappings for the same directory ('a/b').");
      assertManagedDirectoriesParsingError(
          "{'@repo1': [], '@repo1': [] }", "dictionary expression has duplicate key: \"@repo1\"");
      assertManagedDirectoriesParsingError(
          "{'@repo1': ['a/b'], '@repo2': ['a/b/c/..'] }",
          "managed_directories attribute should not contain multiple (or duplicate)"
              + " repository mappings for the same directory ('a/b/c/..').");
      assertManagedDirectoriesParsingError(
          "{'@repo1': ['a'], '@repo2': ['a/b'] }",
          "managed_directories attribute value can not contain nested mappings."
              + " 'a/b' is a descendant of 'a'.");
      assertManagedDirectoriesParsingError(
          "{'@repo1': ['a/b'], '@repo2': ['a'] }",
          "managed_directories attribute value can not contain nested mappings."
              + " 'a/b' is a descendant of 'a'.");

      assertManagedDirectoriesParsingError(
          "{'repo1': []}",
          "Cannot parse repository name 'repo1'. Repository name should start with '@'.");
    } finally {
      PrecomputedValue.STARLARK_SEMANTICS.set(injectable, semantics);
    }
  }

  private WorkspaceFileValue createWorkspaceFileValueForTest() throws Exception {
    WorkspaceFileValue workspaceFileValue =
        parseWorkspaceFileValue(
            "workspace(",
            "  name = 'rr',",
            "  managed_directories = {'@repo1': ['dir1', 'dir2'], '@repo2': ['dir3/dir1/..']}",
            ")");
    ImmutableMap<PathFragment, RepositoryName> managedDirectories =
        workspaceFileValue.getManagedDirectories();
    assertThat(managedDirectories).isNotNull();
    assertThat(managedDirectories).hasSize(3);
    assertThat(managedDirectories)
        .containsExactly(
            PathFragment.create("dir1"), RepositoryName.create("@repo1"),
            PathFragment.create("dir2"), RepositoryName.create("@repo1"),
            PathFragment.create("dir3"), RepositoryName.create("@repo2"));
    return workspaceFileValue;
  }

  private void assertManagedDirectoriesParsingError(
      String managedDirectoriesValue, String expectedError) throws Exception {
    parseWorkspaceFileValueWithError(
        expectedError,
        "workspace(",
        "  name = 'rr',",
        "  managed_directories = " + managedDirectoriesValue,
        ")");
  }

  private WorkspaceFileValue parseWorkspaceFileValue(String... lines) throws Exception {
    WorkspaceFileValue workspaceFileValue = parseWorkspaceFileValueImpl(lines);
    Package pkg = workspaceFileValue.getPackage();
    if (pkg.containsErrors()) {
      throw new RuntimeException(
          Preconditions.checkNotNull(Iterables.getFirst(eventCollector, null)).getMessage());
    }
    return workspaceFileValue;
  }

  private void parseWorkspaceFileValueWithError(String expectedError, String... lines)
      throws Exception {
    WorkspaceFileValue workspaceFileValue = parseWorkspaceFileValueImpl(lines);
    Package pkg = workspaceFileValue.getPackage();
    assertThat(pkg.containsErrors()).isTrue();
    assertContainsEvent(expectedError);
  }

  private WorkspaceFileValue parseWorkspaceFileValueImpl(String[] lines)
      throws IOException, InterruptedException {
    RootedPath workspaceFile = createWorkspaceFile(lines);
    WorkspaceFileKey key = WorkspaceFileValue.key(workspaceFile);
    EvaluationResult<WorkspaceFileValue> result = eval(key);
    return result.get(key);
  }

  @Test
  public void testInvalidRepo() throws Exception {
    // Test intentionally introduces errors.
    reporter.removeHandler(failFastHandler);

    RootedPath workspacePath = createWorkspaceFile("workspace(name = 'foo$')");
    SkyKey key = ExternalPackageFunction.key(workspacePath);
    EvaluationResult<PackageValue> evaluationResult = eval(key);
    Package pkg = evaluationResult.get(key).getPackage();
    assertThat(pkg.containsErrors()).isTrue();
    assertContainsEvent("foo$ is not a legal workspace name");
  }

  @Test
  public void testBindFunction() throws Exception {
    String[] lines = {"bind(name = 'foo/bar',", "actual = '//foo:bar')"};
    RootedPath workspacePath = createWorkspaceFile(lines);

    SkyKey key = ExternalPackageFunction.key(workspacePath);
    EvaluationResult<PackageValue> evaluationResult = eval(key);
    Package pkg = evaluationResult.get(key).getPackage();
    assertThat(getLabelMapping(pkg, "foo/bar"))
        .isEqualTo(Label.parseAbsolute("//foo:bar", ImmutableMap.of()));
    assertNoEvents();
  }

  @Test
  public void testBindArgsReversed() throws Exception {
    String[] lines = {"bind(actual = '//foo:bar', name = 'foo/bar')"};
    RootedPath workspacePath = createWorkspaceFile(lines);

    SkyKey key = ExternalPackageFunction.key(workspacePath);
    EvaluationResult<PackageValue> evaluationResult = eval(key);
    Package pkg = evaluationResult.get(key).getPackage();
    assertThat(getLabelMapping(pkg, "foo/bar"))
        .isEqualTo(Label.parseAbsolute("//foo:bar", ImmutableMap.of()));
    assertNoEvents();
  }

  @Test
  public void testNonExternalBinding() throws Exception {
    // Test intentionally introduces errors.
    reporter.removeHandler(failFastHandler);

    // name must be a valid label name.
    String[] lines = {"bind(name = 'foo:bar', actual = '//bar/baz')"};
    RootedPath workspacePath = createWorkspaceFile(lines);

    SkyKey key = ExternalPackageFunction.key(workspacePath);
    EvaluationResult<PackageValue> evaluationResult = eval(key);
    Package pkg = evaluationResult.get(key).getPackage();
    assertThat(pkg.containsErrors()).isTrue();
    assertContainsEvent("target names may not contain ':'");
  }

  @Test
  public void testWorkspaceFileParsingError() throws Exception {
    // Test intentionally introduces errors.
    reporter.removeHandler(failFastHandler);

    // //external:bar:baz is not a legal package.
    String[] lines = {"bind(name = 'foo/bar', actual = '//external:bar:baz')"};
    RootedPath workspacePath = createWorkspaceFile(lines);

    SkyKey key = ExternalPackageFunction.key(workspacePath);
    EvaluationResult<PackageValue> evaluationResult = eval(key);
    Package pkg = evaluationResult.get(key).getPackage();
    assertThat(pkg.containsErrors()).isTrue();
    assertContainsEvent("target names may not contain ':'");
  }

  @Test
  public void testNoWorkspaceFile() throws Exception {
    // Create and immediately delete to make sure we got the right file.
    RootedPath workspacePath = createWorkspaceFile();
    workspacePath.asPath().delete();

    SkyKey key = ExternalPackageFunction.key(workspacePath);
    EvaluationResult<PackageValue> evaluationResult = eval(key);
    Package pkg = evaluationResult.get(key).getPackage();
    assertThat(pkg.containsErrors()).isFalse();
    assertNoEvents();
  }

  @Test
  public void testListBindFunction() throws Exception {
    String[] lines = {
      "L = ['foo', 'bar']", "bind(name = '%s/%s' % (L[0], L[1]),", "actual = '//foo:bar')"
    };
    RootedPath workspacePath = createWorkspaceFile(lines);

    SkyKey key = ExternalPackageFunction.key(workspacePath);
    EvaluationResult<PackageValue> evaluationResult = eval(key);
    Package pkg = evaluationResult.get(key).getPackage();
    assertThat(getLabelMapping(pkg, "foo/bar"))
        .isEqualTo(Label.parseAbsolute("//foo:bar", ImmutableMap.of()));
    assertNoEvents();
  }

  @Test
  public void testWorkspaceFileValueListener() throws Exception {
    // Normally, syscalls cache is reset in the sync() method of the SkyframeExecutor, before
    // diffing.
    // But here we are calling only actual diffing part, exposed for testing:
    // handleDiffsForTesting(), so we better turn off the syscalls cache.
    skyframeExecutor.turnOffSyscallCacheForTesting();

    createWorkspaceFile("workspace(name = 'old')");
    skyframeExecutor.handleDiffsForTesting(NullEventHandler.INSTANCE);
    assertThat(testManagedDirectoriesKnowledge.getLastWorkspaceName()).isEqualTo("old");
    assertThat(testManagedDirectoriesKnowledge.getCnt()).isEqualTo(1);

    createWorkspaceFile("workspace(name = 'changed')");
    skyframeExecutor.handleDiffsForTesting(NullEventHandler.INSTANCE);
    assertThat(testManagedDirectoriesKnowledge.getLastWorkspaceName()).isEqualTo("changed");
    assertThat(testManagedDirectoriesKnowledge.getCnt()).isEqualTo(2);
  }

  @Test
  public void testDoNotSymlinkInExecroot() throws Exception {
    StarlarkSemantics semantics = getStarlarkSemantics();
    Injectable injectable = getSkyframeExecutor().injectable();

    try {
      StarlarkSemantics semanticsWithNinjaActions =
          StarlarkSemantics.builder()
              .setBool(BuildLanguageOptions.EXPERIMENTAL_NINJA_ACTIONS, true)
              .build();
      PrecomputedValue.STARLARK_SEMANTICS.set(injectable, semanticsWithNinjaActions);

      assertThat(
              parseWorkspaceFileValue("toplevel_output_directories(paths = [\"out\"])")
                  .getDoNotSymlinkInExecrootPaths())
          .containsExactly("out");
      assertThat(
              parseWorkspaceFileValue(
                      "toplevel_output_directories(paths = [\"out\", \"one more with"
                          + " space\"])")
                  .getDoNotSymlinkInExecrootPaths())
          .containsExactly("out", "one more with space");
      // Empty sequence is allowed.
      assertThat(
              parseWorkspaceFileValue("toplevel_output_directories(paths = [])")
                  .getDoNotSymlinkInExecrootPaths())
          .isEmpty();

      // Test now intentionally introduces errors.
      reporter.removeHandler(failFastHandler);

      parseWorkspaceFileValueWithError(
          "toplevel_output_directories should not "
              + "contain duplicate values: \"out\" is specified more then once.",
          "toplevel_output_directories(paths = [\"out\", \"out\"])");
      parseWorkspaceFileValueWithError(
          "toplevel_output_directories can only accept "
              + "top level directories under workspace, \"out/subdir\" "
              + "can not be specified as an attribute.",
          "toplevel_output_directories(paths = [\"out/subdir\"])");
      parseWorkspaceFileValueWithError(
          "Empty path can not be passed to " + "toplevel_output_directories.",
          "toplevel_output_directories(paths = [\"\"])");
      parseWorkspaceFileValueWithError(
          "toplevel_output_directories can only "
              + "accept top level directories under workspace, \"/usr/local/bin\" "
              + "can not be specified as an attribute.",
          "toplevel_output_directories(paths = [\"/usr/local/bin\"])");
    } finally {
      PrecomputedValue.STARLARK_SEMANTICS.set(injectable, semantics);
    }
  }

  @Test
  public void testMangledExternalWorkspaceFileIsIgnored() throws Exception {
    scratch.file("secondary/WORKSPACE", "garbage");
    RootedPath workspace =
        createWorkspaceFile(
            "workspace(name = 'good')",
            "local_repository(name = \"secondary\", path = \"./secondary/\")");

    SkyKey key1 = WorkspaceFileValue.key(workspace, 1);
    EvaluationResult<WorkspaceFileValue> result1 = eval(key1);
    WorkspaceFileValue value1 = result1.get(key1);
    RepositoryName good = RepositoryName.create("@good");
    RepositoryName main = RepositoryName.create("@");
    RepositoryName secondary = RepositoryName.create("@secondary");
    assertThat(value1.getRepositoryMapping()).containsEntry(secondary, ImmutableMap.of(good, main));
    assertNoEvents();
  }

  private static class TestManagedDirectoriesKnowledge implements ManagedDirectoriesKnowledge {
    private String lastWorkspaceName;
    private int cnt = 0;

    @Nullable
    @Override
    public RepositoryName getOwnerRepository(PathFragment relativePathFragment) {
      return null;
    }

    @Override
    public ImmutableSet<PathFragment> getManagedDirectories(RepositoryName repositoryName) {
      return null;
    }

    @Override
    public boolean workspaceHeaderReloaded(
        @Nullable WorkspaceFileValue oldValue, @Nullable WorkspaceFileValue newValue) {
      if (Objects.equals(oldValue, newValue)) {
        return false;
      }
      ++cnt;
      lastWorkspaceName = newValue != null ? newValue.getPackage().getWorkspaceName() : null;
      return true;
    }

    private String getLastWorkspaceName() {
      return lastWorkspaceName;
    }

    private int getCnt() {
      return cnt;
    }
  }

  private static class TestManagedDirectoriesListener implements ManagedDirectoriesListener {
    @Nullable private Set<RepositoryName> repositoryNames;

    @Override
    public void onManagedDirectoriesRefreshed(Set<RepositoryName> repositoryNames) {
      this.repositoryNames = repositoryNames;
    }

    @Nullable
    public Set<RepositoryName> getRepositoryNames() {
      return repositoryNames;
    }

    public void reset() {
      repositoryNames = null;
    }
  }

  // tests of splitAST, an internal helper function

  @Test
  public void testSplitASTNoLoad() {
    List<StarlarkFile> asts = getASTs("foo_bar = 1");
    assertThat(asts).hasSize(1);
    assertThat(asts.get(0).getStatements()).hasSize(1);
  }

  @Test
  public void testSplitASTOneLoadAtTop() {
    List<StarlarkFile> asts = getASTs("load('//:foo.bzl', 'bar')", "foo_bar = 1");
    assertThat(asts).hasSize(1);
    assertThat(asts.get(0).getStatements()).hasSize(2);
  }

  @Test
  public void testSplitASTOneLoad() {
    List<StarlarkFile> asts = getASTs("foo_bar = 1", "load('//:foo.bzl', 'bar')");
    assertThat(asts).hasSize(2);
    assertThat(asts.get(0).getStatements()).hasSize(1);
    assertThat(asts.get(1).getStatements()).hasSize(1);
  }

  @Test
  public void testSplitASTTwoSuccessiveLoads() {
    List<StarlarkFile> asts =
        getASTs("foo_bar = 1", "load('//:foo.bzl', 'bar')", "load('//:bar.bzl', 'foo')");
    assertThat(asts).hasSize(2);
    assertThat(asts.get(0).getStatements()).hasSize(1);
    assertThat(asts.get(1).getStatements()).hasSize(2);
  }

  @Test
  public void testSplitASTTwoSucessiveLoadsWithNonLoadStatement() {
    List<StarlarkFile> asts =
        getASTs(
            "foo_bar = 1",
            "load('//:foo.bzl', 'bar')",
            "load('//:bar.bzl', 'foo')",
            "local_repository(name = 'foobar', path = '/bar/foo')");
    assertThat(asts).hasSize(2);
    assertThat(asts.get(0).getStatements()).hasSize(1);
    assertThat(asts.get(1).getStatements()).hasSize(3);
  }

  @Test
  public void testSplitASTThreeLoadsThreeSegments() {
    List<StarlarkFile> asts =
        getASTs(
            "foo_bar = 1",
            "load('//:foo.bzl', 'bar')",
            "load('//:bar.bzl', 'foo')",
            "local_repository(name = 'foobar', path = '/bar/foo')",
            "load('@foobar//:baz.bzl', 'bleh')");
    assertThat(asts).hasSize(3);
    assertThat(asts.get(0).getStatements()).hasSize(1);
    assertThat(asts.get(1).getStatements()).hasSize(3);
    assertThat(asts.get(2).getStatements()).hasSize(1);
  }

  @Test
  public void testSplitASTThreeLoadsThreeSegmentsWithContent() {
    List<StarlarkFile> asts =
        getASTs(
            "foo_bar = 1",
            "load('//:foo.bzl', 'bar')",
            "load('//:bar.bzl', 'foo')",
            "local_repository(name = 'foobar', path = '/bar/foo')",
            "load('@foobar//:baz.bzl', 'bleh')",
            "bleh()");
    assertThat(asts).hasSize(3);
    assertThat(asts.get(0).getStatements()).hasSize(1);
    assertThat(asts.get(1).getStatements()).hasSize(3);
    assertThat(asts.get(2).getStatements()).hasSize(2);
  }

  private static ImmutableList<StarlarkFile> getASTs(String... lines) {
    return WorkspaceFileFunction.splitAST(StarlarkFile.parse(ParserInput.fromLines(lines)));
  }
}


text:
package uk.ac.ebi.eva.pipeline.parameters.validation;

import org.junit.Before;
import org.junit.Test;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.JobParametersInvalidException;

import uk.ac.ebi.eva.pipeline.parameters.JobParametersNames;

public class ConfigChunkSizeValidatorTest {
    private ConfigChunkSizeValidator validator;

    private JobParametersBuilder jobParametersBuilder;

    @Before
    public void setUp() throws Exception {
        validator = new ConfigChunkSizeValidator();
    }

    @Test
    public void chunkSizeIsValid() throws JobParametersInvalidException {
        jobParametersBuilder = new JobParametersBuilder();
        jobParametersBuilder.addString(JobParametersNames.CONFIG_CHUNK_SIZE, "11");
        validator.validate(jobParametersBuilder.toJobParameters());
    }

    @Test(expected = JobParametersInvalidException.class)
    public void chunkSizeIsZero() throws JobParametersInvalidException {
        jobParametersBuilder = new JobParametersBuilder();
        jobParametersBuilder.addString(JobParametersNames.CONFIG_CHUNK_SIZE, "0");
        validator.validate(jobParametersBuilder.toJobParameters());
    }

    @Test(expected = JobParametersInvalidException.class)
    public void chunkSizeIsNegative() throws JobParametersInvalidException {
        jobParametersBuilder = new JobParametersBuilder();
        jobParametersBuilder.addString(JobParametersNames.CONFIG_CHUNK_SIZE, "-1");
        validator.validate(jobParametersBuilder.toJobParameters());
    }

    @Test(expected = JobParametersInvalidException.class)
    public void chunkSizeIsNotValid() throws JobParametersInvalidException {
        jobParametersBuilder = new JobParametersBuilder();
        jobParametersBuilder.addString(JobParametersNames.CONFIG_CHUNK_SIZE, "hello");
        validator.validate(jobParametersBuilder.toJobParameters());
    }

    @Test(expected = JobParametersInvalidException.class)
    public void chunkSizeIsEmpty() throws JobParametersInvalidException {
        jobParametersBuilder = new JobParametersBuilder();
        jobParametersBuilder.addString(JobParametersNames.CONFIG_CHUNK_SIZE, "");
        validator.validate(jobParametersBuilder.toJobParameters());
    }

    @Test(expected = JobParametersInvalidException.class)
    public void chunkSizeIsNull() throws JobParametersInvalidException {
        jobParametersBuilder = new JobParametersBuilder();
        jobParametersBuilder.addString(JobParametersNames.CONFIG_CHUNK_SIZE, null);
        validator.validate(jobParametersBuilder.toJobParameters());
    }
}

redpajama_set_name: RedPajamaGithub


text:
using System;
using System.Collections;
using System.Collections.Specialized;

namespace System.Web.UI.WebControls
{
	public class DataKey : IStateManager
	{
		IOrderedDictionary keyTable;
		string[] keyNames;
		bool trackViewState;
		IOrderedDictionary readonlyKeyTable;

		public DataKey (IOrderedDictionary keyTable)
		{
			this.keyTable = keyTable;
		}

		public DataKey (IOrderedDictionary keyTable, string[] keyNames)
		{
			this.keyTable = keyTable;
			this.keyNames = keyNames;
		}

		public virtual object this [int index] {
			get { return keyTable [index]; }
		}

		public virtual object this [string name] {
			get { return keyTable [name]; }
		}

		public virtual object Value {
			get { return keyTable [0]; }
		}

		public virtual IOrderedDictionary Values {
			get {
				if (readonlyKeyTable == null) {
					if (keyTable is OrderedDictionary)
						readonlyKeyTable = ((OrderedDictionary)keyTable).AsReadOnly ();
					else
						readonlyKeyTable = keyTable;
				}
				return readonlyKeyTable;
			}
		}

		protected virtual void LoadViewState (object savedState)
		{
			if (savedState is Pair) {
				Pair p = (Pair) savedState;
				object[] akeys = (object[]) p.First;
				object[] avals = (object[]) p.Second;
				for (int n=0; n<akeys.Length; n++) {
					keyTable [akeys[n]] = avals [n];
				}
			} else if (savedState is object[]) {
				object[] avals = (object[]) savedState;
				for (int n=0; n<avals.Length; n++)
					keyTable [keyNames[n]] = avals [n];
			}
		}

		protected virtual object SaveViewState ()
		{
			if (keyTable.Count == 0) return null;

			if (keyNames != null) {
				object[] avals = new object [keyTable.Count];
				int n=0;
				foreach (object val in keyTable.Values)
					avals [n++] = val;
				return avals;
			} else {
				object[] avals = new object [keyTable.Count];
				object[] akeys = new object [keyTable.Count];
				int n=0;
				foreach (DictionaryEntry de in keyTable) {
					akeys [n] = de.Key;
					avals [n++] = de.Value;
				}
				return new Pair (akeys, avals);
			}
		}

		protected virtual void TrackViewState ()
		{
			trackViewState = true;
		}

		protected virtual bool IsTrackingViewState {
			get { return trackViewState; }
		}

		void IStateManager.LoadViewState (object savedState)
		{
			LoadViewState (savedState);
		}

		object IStateManager.SaveViewState ()
		{
			return SaveViewState ();
		}

		void IStateManager.TrackViewState ()
		{
			TrackViewState ();
		}

		bool IStateManager.IsTrackingViewState {
			get { return IsTrackingViewState; }
		}
	}
}
#endif


text:
using System;
using System.IO;
using System.Xml;

namespace RelhaxModpack.Xml
{
#pragma warning disable CS1591
    public class PrimitiveFileReader
    {
        public void ReadPrimitives(BinaryReader reader, XmlNode element, XmlDocument xDoc)
        {
            int len = (int)reader.BaseStream.Length;
            int data = (int)reader.BaseStream.Position + sizeof(int);

            reader.BaseStream.Position = ((int)reader.BaseStream.Position + len - sizeof(int));
            int indexLen = reader.ReadInt32();
            int offset = len - (indexLen + sizeof(int));
            reader.BaseStream.Position = offset;
            long oldDataLen = 4;
            while (offset < (len - 4))
            {
                int entryDataLen = 0;
                int entryNameLen = 0;
                for (int i = 0; i < (len - (int)reader.BaseStream.Position); i++)
                {
                    if (reader.ReadByte() != 0x00)
                    {
                        reader.BaseStream.Position = (int)reader.BaseStream.Position - 1;
                        entryDataLen = reader.ReadInt32();
                        break;
                    }
                }

                for (int i = 0; i < (len - (int)reader.BaseStream.Position); i++)
                {
                    if (reader.ReadByte() != 0x00)
                    {
                        reader.BaseStream.Position = (int)reader.BaseStream.Position - 1;
                        entryNameLen = reader.ReadInt32();
                        break;
                    }
                }

                string entryStr = new string(reader.ReadChars(entryNameLen), 0, entryNameLen);

                XmlNode XentryStr = xDoc.CreateElement("primitive");
                XmlAttribute attr = xDoc.CreateAttribute("id");
                attr.InnerText = entryStr;
                XentryStr.Attributes.Append(attr);

                XmlNode XentryDataPos = xDoc.CreateElement("position");
                XentryDataPos.InnerText = Convert.ToString(oldDataLen);
                XmlNode XentryDataLen = xDoc.CreateElement("length");
                XentryDataLen.InnerText = Convert.ToString(entryDataLen);
                oldDataLen += (entryDataLen + 3) & (~3L);

                XentryStr.AppendChild(XentryDataPos);
                XentryStr.AppendChild(XentryDataLen);

                offset = (int)reader.BaseStream.Position + entryNameLen;
                element.AppendChild(XentryStr);
            }
        }
    }
#pragma warning restore CS1591
}


text:
#include <warn/push>
#include <warn/ignore/all>
#include <QGraphicsDropShadowEffect>
#include <QPainter>
#include <QString>
#include <QPainterPath>
#include <QSvgRenderer>
#include <QPainter>
#include <QImage>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <warn/pop>

#include <inviwo/qt/editor/linkgraphicsitem.h>
#include <inviwo/core/ports/port.h>
#include <inviwo/core/links/propertylink.h>
#include <inviwo/qt/editor/processorlinkgraphicsitem.h>
#include <inviwo/qt/editor/processorgraphicsitem.h>
#include <inviwo/core/common/inviwoapplication.h>
#include <inviwo/core/network/processornetwork.h>

#include <modules/qtwidgets/inviwoqtutils.h>
#include <inviwo/core/util/document.h>

#include <fmt/format.h>

namespace inviwo {

LinkGraphicsItem::LinkGraphicsItem(ivec3 color) : color_(color.r, color.g, color.b) {
    setZValue(LINKGRAPHICSITEM_DEPTH);
}

LinkGraphicsItem::~LinkGraphicsItem() = default;

void LinkGraphicsItem::paint(QPainter* p, const QStyleOptionGraphicsItem*, QWidget*) {
    if (isSelected()) {
        p->setPen(QPen(Qt::darkRed, 2.0, Qt::DotLine, Qt::RoundCap));
    } else {
        p->setPen(QPen(color_, 2.0, Qt::DotLine, Qt::RoundCap));
    }
    p->drawPath(path_);
}

QPainterPath LinkGraphicsItem::obtainCurvePath() const {
    QPainterPath bezierCurve;

    const auto start = getStartPoint();
    const auto end = getEndPoint();

    const auto diff = start - end;
    const auto dist = std::sqrt(QPointF::dotProduct(diff, diff));
    const auto strength = 1.0 + std::min(50.0, 2.0 * dist);

    bezierCurve.moveTo(getStartPoint());
    bezierCurve.cubicTo(getStartPoint() + strength * getStartDir(),
                        getEndPoint() + strength * getEndDir(), getEndPoint());
    return bezierCurve;
}

QPainterPath LinkGraphicsItem::shape() const {
    QPainterPathStroker pathStrocker;
    pathStrocker.setWidth(10.0);
    return pathStrocker.createStroke(path_);
}

QRectF LinkGraphicsItem::boundingRect() const { return rect_; }

void LinkGraphicsItem::updateShape() {
    const auto start = utilqt::toGLM(getStartPoint());
    const auto end = utilqt::toGLM(getEndPoint());

    rect_ = QRectF(utilqt::toQPoint(glm::min(start, end)), utilqt::toQPoint(glm::max(start, end)))
                .marginsAdded(QMarginsF{40.0, 10.0, 40.0, 10.0});

    path_ = obtainCurvePath();

    prepareGeometryChange();
}

LinkConnectionDragGraphicsItem::LinkConnectionDragGraphicsItem(ProcessorLinkGraphicsItem* outLink,
                                                               QPointF endPos)
    : LinkGraphicsItem(), inLeft_(endPos), inRight_(endPos), outLink_(outLink) {}

LinkConnectionDragGraphicsItem::~LinkConnectionDragGraphicsItem() = default;

ProcessorLinkGraphicsItem* LinkConnectionDragGraphicsItem::getSrcProcessorLinkGraphicsItem() const {
    return outLink_;
}

ProcessorGraphicsItem* LinkConnectionDragGraphicsItem::getSrcProcessorGraphicsItem() const {
    return outLink_->getProcessorGraphicsItem();
}

QPointF LinkConnectionDragGraphicsItem::compare(const QPointF startLeft, const QPointF& startRight,
                                                const QPointF& endLeft, const QPointF& endRight,
                                                const QPointF& left, const QPointF& center,
                                                const QPointF& right) {

    if (startLeft.x() > endRight.x()) {
        return left;
    } else if (startRight.x() < endLeft.x()) {
        return right;
    } else {
        return center;
    }
}

QPointF LinkConnectionDragGraphicsItem::getStartPoint() const {
    const auto startLeft = outLink_->getLeftPos();
    const auto startRight = outLink_->getRightPos();
    return compare(startLeft, startRight, inLeft_, inRight_, startLeft, startRight, startRight);
}
QPointF LinkConnectionDragGraphicsItem::getEndPoint() const {
    const auto startLeft = outLink_->getLeftPos();
    const auto startRight = outLink_->getRightPos();
    return compare(startLeft, startRight, inLeft_, inRight_, inRight_, inRight_, inLeft_);
}

QPointF LinkConnectionDragGraphicsItem::getStartDir() const {
    const auto qp = QPointF(1, 0);
    const auto startLeft = outLink_->getLeftPos();
    const auto startRight = outLink_->getRightPos();
    return compare(startLeft, startRight, inLeft_, inRight_, -qp, qp, qp);
}
QPointF LinkConnectionDragGraphicsItem::getEndDir() const {
    const auto qp = QPointF(1, 0);
    const auto startLeft = outLink_->getLeftPos();
    const auto startRight = outLink_->getRightPos();
    return compare(startLeft, startRight, inLeft_, inRight_, qp, qp, -qp);
}

void LinkConnectionDragGraphicsItem::setEndPoint(QPointF endPoint) {
    inLeft_ = endPoint;
    inRight_ = endPoint;
    updateShape();
}

void LinkConnectionDragGraphicsItem::setEndPoint(QPointF endPointLeft, QPointF endPointRight) {
    inLeft_ = endPointLeft;
    inRight_ = endPointRight;
    updateShape();
}

void LinkConnectionDragGraphicsItem::reactToProcessorHover(ProcessorGraphicsItem* processor) {
    if (processor != nullptr) {
        inRight_ = processor->getLinkGraphicsItem()->getRightPos();
        inLeft_ = processor->getLinkGraphicsItem()->getLeftPos();
        updateShape();
    }
}

LinkConnectionGraphicsItem::LinkConnectionGraphicsItem(ProcessorLinkGraphicsItem* outLink,
                                                       ProcessorLinkGraphicsItem* inLink)
    : LinkConnectionDragGraphicsItem(outLink, QPointF(0, 0)), inLink_(inLink) {
    setFlags(ItemIsSelectable | ItemIsFocusable);

    outLink_->addLink(this);
    inLink_->addLink(this);

    setVisible(outLink_->isVisible() && inLink_->isVisible());
}

LinkConnectionGraphicsItem::~LinkConnectionGraphicsItem() {
    outLink_->removeLink(this);
    inLink_->removeLink(this);
}

QPointF LinkConnectionGraphicsItem::getStartPoint() const {
    const auto startLeft = outLink_->getLeftPos();
    const auto startRight = outLink_->getRightPos();
    const auto endRight = inLink_->getRightPos();
    const auto endLeft = inLink_->getLeftPos();
    return compare(startLeft, startRight, endLeft, endRight, startLeft, startRight, startRight);
}
QPointF LinkConnectionGraphicsItem::getEndPoint() const {
    const auto startLeft = outLink_->getLeftPos();
    const auto startRight = outLink_->getRightPos();
    const auto endRight = inLink_->getRightPos();
    const auto endLeft = inLink_->getLeftPos();
    return compare(startLeft, startRight, endLeft, endRight, endRight, endRight, endLeft);
}

QPointF LinkConnectionGraphicsItem::getStartDir() const {
    const auto qp = QPointF(1, 0);
    const auto startLeft = outLink_->getLeftPos();
    const auto startRight = outLink_->getRightPos();
    const auto endRight = inLink_->getRightPos();
    const auto endLeft = inLink_->getLeftPos();
    return compare(startLeft, startRight, endLeft, endRight, -qp, qp, qp);
}
QPointF LinkConnectionGraphicsItem::getEndDir() const {
    const auto qp = QPointF(1, 0);
    const auto startLeft = outLink_->getLeftPos();
    const auto startRight = outLink_->getRightPos();
    const auto endRight = inLink_->getRightPos();
    const auto endLeft = inLink_->getLeftPos();
    return compare(startLeft, startRight, endLeft, endRight, qp, qp, -qp);
}

ProcessorLinkGraphicsItem* LinkConnectionGraphicsItem::getDestProcessorLinkGraphicsItem() const {
    return inLink_;
}

ProcessorGraphicsItem* LinkConnectionGraphicsItem::getDestProcessorGraphicsItem() const {
    return inLink_->getProcessorGraphicsItem();
}

class LinkConnectionGraphicsItemMatchReverse {
public:
    LinkConnectionGraphicsItemMatchReverse(PropertyLink link) : link_(link) {}
    bool operator()(const PropertyLink& link) const {
        return link.getDestination() == link_.getSource() &&
               link.getSource() == link_.getDestination();
    }

private:
    PropertyLink link_;
};

void LinkConnectionGraphicsItem::showToolTip(QGraphicsSceneHelpEvent* e) {
    using namespace std::literals;
    auto p1 = inLink_->getProcessorGraphicsItem()->getProcessor();
    auto p2 = outLink_->getProcessorGraphicsItem()->getProcessor();
    auto network = p1->getNetwork();

    const auto w = scene()->views().front();
    const auto size = utilqt::emToPx(w, 1.5);
    auto img = [&](const auto& file) {
        QSvgRenderer renderer(utilqt::toQString(file));
        QImage image(size, size, QImage::Format_ARGB32);
        image.fill(0);
        QPainter painter(&image);
        renderer.render(&painter);
        return fmt::format("<img src = 'data:image/png;base64,{}'/>", utilqt::toBase64(image));
    };
    const auto imgRight = img(":/svgicons/link-right.svg"sv);
    const auto imgBi = img(":/svgicons/link-bidirectional.svg"sv);
    const auto imgLeft = img(":/svgicons/link-left.svg"sv);

    using A = utildoc::TableBuilder::ArrributeWrapper;
    using P = Document::PathComponent;
    Document doc;
    utildoc::TableBuilder tb(doc.handle(), P::end());
    tb(A{{{"style", "color:white;"}, {"align", "right"}}, p1->getIdentifier()}, "",
       A{{{"style", "color:white;"}, {"align", "left"}}, p2->getIdentifier()});

    const std::unordered_map<std::string, std::string> right = {{"align", "right"}};
    const std::unordered_map<std::string, std::string> left = {{"align", "left"}};
    for (const auto& link : network->getLinksBetweenProcessors(p1, p2)) {
        auto src = link.getSource();
        auto dst = link.getDestination();
        if (network->isLinkedBidirectional(src, dst)) {
            if (src < dst) {
                tb(A{right, src->getDisplayName()}, imgBi, A{left, dst->getDisplayName()});
            }
        } else if (src->getOwner()->getProcessor() == p1) {
            tb(A{right, src->getDisplayName()}, imgRight, A{left, dst->getDisplayName()});
        } else {
            tb(A{right, dst->getDisplayName()}, imgLeft, A{left, src->getDisplayName()});
        }
    }
    showToolTipHelper(e, utilqt::toQString(doc));
}

}  // namespace inviwo


text:
layout: post
---
After the long weekend we were back at the Makers Academy today.  It's amazing how tightly bonded I feel to many of my co-coders, I was really glad to see them again.  And to get on with the serious business of designing a database in PostgreSQL.

The interface leaves a lot to be desired but it's effective, that's for sure.  The practical project we're building to hone our skills on is a bookmark manager, allowing us to Create, Retrieve, Update and Delete entries (CRUD).  We're also building a web interface for it so that should give us some more CSS experience.

![Lunchtime talk from Alex Tercete]({{ site.baseurl }}/images/week4_lunchtimeTalk.JPG)

Lunchtime talk by Alex Tercete from Energy Helpline on Commandless Git

<!--more-->

```
List of databases
Name             |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges
------------------------------+----------+----------+-------------+-------------+-----------------------
bookmark_manager_development | sanjsanj | UTF8     | en_GB.UTF-8 | en_GB.UTF-8 |
bookmark_manager_test        | sanjsanj | UTF8     | en_GB.UTF-8 | en_GB.UTF-8 |
postgres                     | sanjsanj | UTF8     | en_GB.UTF-8 | en_GB.UTF-8 |
sanjsanj                     | sanjsanj | UTF8     | en_GB.UTF-8 | en_GB.UTF-8 |
```

Apparently by the end of the week we'll know what the hell any of this is supposed to mean.


text:
package com.zoowii.jpa_utils.util;

import com.google.common.base.Function;
import com.zoowii.jpa_utils.util.functions.Function2;

import java.util.*;

public class ListUtil {
    public static Map<String, Object> hashmap(Object... params) {
        Map<String, Object> result = new HashMap<String, Object>();
        for (int i = 0; i < params.length; i += 2) {
            if (i + 1 >= params.length) {
                break;
            }
            Object param1 = params[i];
            Object param2 = params[i + 1];
            if (param1 == null) {
                continue;
            }
            String key = param1.toString();
            result.put(key, param2);
        }
        return result;
    }

    public static <T> List<T> seq(T... items) {
        List<T> result = new ArrayList<T>();
        for (T item : items) {
            result.add(item);
        }
        return result;
    }

    public static List<Integer> intToList(int[] arr) {
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < arr.length; i++) {
            list.add(arr[i]);
        }
        return list;
    }

    public static <T1, T2> List<T2> map(List<T1> source, Function<T1, T2> fn) {
        if (source == null || fn == null) {
            return null;
        }
        List<T2> result = new ArrayList<T2>();
        for (T1 item : source) {
            result.add(fn.apply(item));
        }
        return result;
    }

    public static <T> T reduce(List<T> source, T start, Function2<T, T, T> fn) {
        if (fn == null || source == null) {
            return start;
        }
        T result = start;
        for (T item : source) {
            result = fn.apply(result, item);
        }
        return result;
    }

    public static <T> T reduce(List<T> source, Function2<T, T, T> fn) {
        if (fn == null || size(source) < 1) {
            return null;
        }
        return reduce(rest(source), first(source), fn);
    }

    public static <T> List<T> rest(List<T> source) {
        if (source == null) {
            return null;
        }
        List<T> result = clone(source);
        if (size(result) > 0) {
            result.remove(0);
        }
        return result;
    }

    public static <T> List<T> clone(List<T> source) {
        if (source == null) {
            return null;
        }
        return map(source, new Function<T, T>() {
            @Override
            public T apply(T t) {
                return t;
            }
        });
    }

    public static <T> List<T> filter(List<T> source, Function<T, Boolean> fn) {
        if (source == null || fn == null) {
            return source;
        }
        List<T> result = new ArrayList<T>();
        for (T item : source) {
            Boolean predResult = fn.apply(item);
            if (predResult != null && predResult) {
                result.add(item);
            }
        }
        return result;
    }

    public static <T> T first(List<T> source, Function<T, Boolean> fn) {
        if (source == null || fn == null) {
            return null;
        }
        for (T item : source) {
            Boolean predResult = fn.apply(item);
            if (predResult != null && predResult) {
                return item;
            }
        }
        return null;
    }

    public static <T> Function<T, Boolean> not(final Function<T, Boolean> fn) {
        if (fn == null) {
            return null;
        }
        return new Function<T, Boolean>() {
            @Override
            public Boolean apply(T t) {
                Boolean result = fn.apply(t);
                if (result == null) {
                    return true;
                }
                return !result;
            }
        };
    }

    public static <T> boolean any(List<T> source, Function<T, Boolean> fn) {
        return first(source, fn) != null;
    }

    public static <T> boolean all(List<T> source, Function<T, Boolean> fn) {
        return first(source, not(fn)) == null;
    }

    public static <T> T first(List<T> source) {
        if (source == null || source.size() < 1) {
            return null;
        }
        return source.get(0);
    }

    public static <T> int size(List<T> source) {
        if (source == null) {
            return 0;
        }
        return source.size();
    }

    public static <T> T max(List<T> source, Comparator<T> comparator) {
        if (source == null || comparator == null) {
            return null;
        }
        List<T> sorted = clone(source);
        return Collections.max(sorted, comparator);
    }

    public static <T> T min(List<T> source, Comparator<T> comparator) {
        if (source == null || comparator == null) {
            return null;
        }
        List<T> sorted = clone(source);
        return Collections.min(sorted, comparator);
    }
    public static <T> List<T> cloneList(List<T> source) {
        if(source == null) {
            return null;
        }
        List<T> result = new ArrayList<T>();
        result.addAll(source);
        return result;
    }
}


text:
<?php
/**
 * DO NOT EDIT THIS FILE!
 *
 * This file was automatically generated from external sources.
 *
 * Any manual change here will be lost the next time the SDK
 * is updated. You've been warned!
 */

namespace DTS\eBaySDK\Marketing\Types;

/**
 *
 * @property \DTS\eBaySDK\Marketing\Types\Campaign[] $campaigns
 * @property string $href
 * @property integer $limit
 * @property string $next
 * @property integer $offset
 * @property string $prev
 * @property integer $total
 */
class CampaignPagedCollection extends \DTS\eBaySDK\Types\BaseType
{
    /**
     * @var array Properties belonging to objects of this class.
     */
    private static $propertyTypes = [
        'campaigns' => [
            'type' => 'DTS\eBaySDK\Marketing\Types\Campaign',
            'repeatable' => true,
            'attribute' => false,
            'elementName' => 'campaigns'
        ],
        'href' => [
            'type' => 'string',
            'repeatable' => false,
            'attribute' => false,
            'elementName' => 'href'
        ],
        'limit' => [
            'type' => 'integer',
            'repeatable' => false,
            'attribute' => false,
            'elementName' => 'limit'
        ],
        'next' => [
            'type' => 'string',
            'repeatable' => false,
            'attribute' => false,
            'elementName' => 'next'
        ],
        'offset' => [
            'type' => 'integer',
            'repeatable' => false,
            'attribute' => false,
            'elementName' => 'offset'
        ],
        'prev' => [
            'type' => 'string',
            'repeatable' => false,
            'attribute' => false,
            'elementName' => 'prev'
        ],
        'total' => [
            'type' => 'integer',
            'repeatable' => false,
            'attribute' => false,
            'elementName' => 'total'
        ]
    ];

    /**
     * @param array $values Optional properties and values to assign to the object.
     */
    public function __construct(array $values = [])
    {
        list($parentValues, $childValues) = self::getParentValues(self::$propertyTypes, $values);

        parent::__construct($parentValues);

        if (!array_key_exists(__CLASS__, self::$properties)) {
            self::$properties[__CLASS__] = array_merge(self::$properties[get_parent_class()], self::$propertyTypes);
        }

        $this->setValues(__CLASS__, $childValues);
    }
}


text:
package org.apache.commons.collections4.iterators;

import java.util.ListIterator;

/**
 * Provides basic behaviour for decorating a list iterator with extra functionality.
 * <p>
 * All methods are forwarded to the decorated list iterator.
 *
 * @since 3.0
 * @version $Id$
 */
public class AbstractListIteratorDecorator<E> implements ListIterator<E> {

    /** The iterator being decorated */
    private final ListIterator<E> iterator;

    //-----------------------------------------------------------------------
    /**
     * Constructor that decorates the specified iterator.
     *
     * @param iterator  the iterator to decorate, must not be null
     * @throws NullPointerException if the iterator is null
     */
    public AbstractListIteratorDecorator(final ListIterator<E> iterator) {
        super();
        if (iterator == null) {
            throw new NullPointerException("ListIterator must not be null");
        }
        this.iterator = iterator;
    }

    /**
     * Gets the iterator being decorated.
     *
     * @return the decorated iterator
     */
    protected ListIterator<E> getListIterator() {
        return iterator;
    }

    //-----------------------------------------------------------------------

    /** {@inheritDoc} */
    public boolean hasNext() {
        return iterator.hasNext();
    }

    /** {@inheritDoc} */
    public E next() {
        return iterator.next();
    }

    /** {@inheritDoc} */
    public int nextIndex() {
        return iterator.nextIndex();
    }

    /** {@inheritDoc} */
    public boolean hasPrevious() {
        return iterator.hasPrevious();
    }

    /** {@inheritDoc} */
    public E previous() {
        return iterator.previous();
    }

    /** {@inheritDoc} */
    public int previousIndex() {
        return iterator.previousIndex();
    }

    /** {@inheritDoc} */
    public void remove() {
        iterator.remove();
    }

    /** {@inheritDoc} */
    public void set(final E obj) {
        iterator.set(obj);
    }

    /** {@inheritDoc} */
    public void add(final E obj) {
        iterator.add(obj);
    }

}


text:
namespace boost {
namespace mpl {

template<
      typename BOOST_MPL_AUX_VOID_SPEC_PARAM(Sequence)
    >
struct pop_back
    : pop_back_traits< typename BOOST_MPL_AUX_SEQUENCE_TAG(Sequence) >
        ::template algorithm< Sequence >
{
    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,pop_back,(Sequence))
};

BOOST_MPL_AUX_VOID_SPEC(1, pop_back)

} // namespace mpl
} // namespace boost

#endif // BOOST_MPL_POP_BACK_HPP_INCLUDED


text:
use std::rc::Rc;

use errors::*;
use dbus_nm::DBusNetworkManager;

use connection::{get_active_connections, get_connections, Connection};
use device::{get_device_by_interface, get_devices, Device};
use service::{get_service_state, start_service, stop_service, ServiceState};

pub struct NetworkManager {
    dbus_manager: Rc<DBusNetworkManager>,
}

impl NetworkManager {
    pub fn new() -> Self {
        NetworkManager {
            dbus_manager: Rc::new(DBusNetworkManager::new(None)),
        }
    }

    pub fn with_method_timeout(timeout: u64) -> Self {
        NetworkManager {
            dbus_manager: Rc::new(DBusNetworkManager::new(Some(timeout))),
        }
    }

    /// Starts the Network Manager service.
    ///
    /// # Examples
    ///
    /// ```
    /// use network_manager::NetworkManager;
    /// let state = NetworkManager::start_service(10).unwrap();
    /// println!("{:?}", state);
    /// ```
    pub fn start_service(timeout: u64) -> Result<ServiceState> {
        start_service(timeout)
    }

    /// Stops the Network Manager service.
    ///
    /// # Examples
    ///
    /// ```
    /// use network_manager::NetworkManager;
    /// let state = NetworkManager::stop_service(10).unwrap();
    /// println!("{:?}", state);
    /// ```
    pub fn stop_service(timeout: u64) -> Result<ServiceState> {
        stop_service(timeout)
    }

    /// Gets the state of the Network Manager service.
    ///
    /// # Examples
    ///
    /// ```
    /// use network_manager::NetworkManager;
    /// let state = NetworkManager::get_service_state().unwrap();
    /// println!("{:?}", state);
    /// ```
    pub fn get_service_state() -> Result<ServiceState> {
        get_service_state()
    }

    /// Get a list of Network Manager connections sorted by path.
    ///
    /// # Examples
    ///
    /// ```
    /// use network_manager::NetworkManager;
    /// let manager = NetworkManager::new();
    /// let connections = manager.get_connections().unwrap();
    /// println!("{:?}", connections);
    /// ```
    pub fn get_connections(&self) -> Result<Vec<Connection>> {
        get_connections(&self.dbus_manager)
    }

    pub fn get_active_connections(&self) -> Result<Vec<Connection>> {
        get_active_connections(&self.dbus_manager)
    }

    /// Get a list of Network Manager devices.
    ///
    /// # Examples
    ///
    /// ```
    /// use network_manager::NetworkManager;
    /// let manager = NetworkManager::new();
    /// let devices = manager.get_devices().unwrap();
    /// println!("{:?}", devices);
    /// ```
    pub fn get_devices(&self) -> Result<Vec<Device>> {
        get_devices(&self.dbus_manager)
    }

    pub fn get_device_by_interface(&self, interface: &str) -> Result<Device> {
        get_device_by_interface(&self.dbus_manager, interface)
    }

    pub fn get_state(&self) -> Result<NetworkManagerState> {
        self.dbus_manager.get_state()
    }

    pub fn get_connectivity(&self) -> Result<Connectivity> {
        self.dbus_manager.check_connectivity()
    }

    pub fn is_networking_enabled(&self) -> Result<bool> {
        self.dbus_manager.is_networking_enabled()
    }

    pub fn is_wireless_enabled(&self) -> Result<bool> {
        self.dbus_manager.is_wireless_enabled()
    }
}

impl Default for NetworkManager {
    fn default() -> Self {
        Self::new()
    }
}

#[derive(Clone, Debug, PartialEq)]
pub enum NetworkManagerState {
    Unknown,
    Asleep,
    Disconnected,
    Disconnecting,
    Connecting,
    ConnectedLocal,
    ConnectedSite,
    ConnectedGlobal,
}

impl From<u32> for NetworkManagerState {
    fn from(state: u32) -> Self {
        match state {
            0 => NetworkManagerState::Unknown,
            10 => NetworkManagerState::Asleep,
            20 => NetworkManagerState::Disconnected,
            30 => NetworkManagerState::Disconnecting,
            40 => NetworkManagerState::Connecting,
            50 => NetworkManagerState::ConnectedLocal,
            60 => NetworkManagerState::ConnectedSite,
            70 => NetworkManagerState::ConnectedGlobal,
            _ => {
                warn!("Undefined Network Manager state: {}", state);
                NetworkManagerState::Unknown
            },
        }
    }
}

#[derive(Clone, Debug, PartialEq)]
pub enum Connectivity {
    Unknown,
    None,
    Portal,
    Limited,
    Full,
}

impl From<u32> for Connectivity {
    fn from(state: u32) -> Self {
        match state {
            0 => Connectivity::Unknown,
            1 => Connectivity::None,
            2 => Connectivity::Portal,
            3 => Connectivity::Limited,
            4 => Connectivity::Full,
            _ => {
                warn!("Undefined connectivity state: {}", state);
                Connectivity::Unknown
            },
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_get_connections() {
        let manager = NetworkManager::new();
        let connections = manager.get_connections().unwrap();
        assert!(connections.len() > 0);
    }

    #[test]
    fn test_get_devices() {
        let manager = NetworkManager::new();
        let devices = manager.get_devices().unwrap();
        assert!(devices.len() > 0);
    }

    #[test]
    fn test_get_connectivity() {
        let manager = NetworkManager::new();
        let connectivity = manager.get_connectivity().unwrap();
        assert_eq!(connectivity, Connectivity::Full);
    }

    #[test]
    fn test_start_stop_service() {
        let s = NetworkManager::get_service_state().unwrap();

        assert!(s == ServiceState::Active || s == ServiceState::Inactive);

        match s {
            ServiceState::Active => {
                NetworkManager::stop_service(10).unwrap();
                assert_eq!(
                    ServiceState::Inactive,
                    NetworkManager::get_service_state().unwrap()
                );

                NetworkManager::start_service(10).unwrap();
                assert_eq!(
                    ServiceState::Active,
                    NetworkManager::get_service_state().unwrap()
                );
            },
            ServiceState::Inactive => {
                NetworkManager::start_service(10).unwrap();
                assert_eq!(
                    ServiceState::Active,
                    NetworkManager::get_service_state().unwrap()
                );

                NetworkManager::stop_service(10).unwrap();
                assert_eq!(
                    ServiceState::Inactive,
                    NetworkManager::get_service_state().unwrap()
                );
            },
            _ => (),
        }
    }
}


text:
import React from 'react';
import {getHumanDuration} from '../utils/utils'
import '../styles/SongsList.global.css'

class SongsList extends React.Component {
  constructor(props) {
    super(props)

    this.handlePlayClick = this.handlePlayClick.bind(this)
  }

  handlePlayClick(event) {
    const songIdx = event.currentTarget.dataset.songIdx
    this.props.handlePlaySong(songIdx)
  }

  render() {
    return (

        {this.props.songs.map(function(element, idx){
          const isCurrentSong = (element.id === this.props.player.currentSongId)
          return

              {!isCurrentSong &&
                <button className="bttn bttn-default btn-sm" type="button" onClick={this.handlePlayClick} data-song-idx={idx}></button>}
              {isCurrentSong &&

}

            {element.title}
            {getHumanDuration(element.additional.song_audio.duration)}

        }, this)
        }

    )
  }
}

export default SongsList