text:
<script src="../resources/get-host-info.sub.js"></script>
<script src="test-helpers.sub.js?pipe=sub"></script>
<script>
  var host_info = get_host_info();
  var uri = document.location + '?check-ua-header';

  var headers = new Headers();
  headers.set('User-Agent', 'custom_ua');

  // Check the custom UA case
  fetch(uri, { headers: headers }).then(function(response) {
    return response.text();
  }).then(function(text) {
    if (text == 'custom_ua') {
      parent.postMessage('PASS', '*');
    } else {
      parent.postMessage('withUA FAIL - expected "custom_ua", got "' + text + '"', '*');
    }
  }).catch(function(err) {
    parent.postMessage('withUA FAIL - unexpected error: ' + err, '*');
  });

  // Check the default UA case
  fetch(uri, {}).then(function(response) {
    return response.text();
  }).then(function(text) {
    if (text == 'NO_UA') {
      parent.postMessage('PASS', '*');
    } else {
      parent.postMessage('noUA FAIL - expected "NO_UA", got "' + text + '"', '*');
    }
  }).catch(function(err) {
    parent.postMessage('noUA FAIL - unexpected error: ' + err, '*');
  });

  var uri = document.location + '?check-accept-header';
  var headers = new Headers();
  headers.set('Accept', 'hmm');

  // Check for custom accept header
  fetch(uri, { headers: headers }).then(function(response) {
    return response.text();
  }).then(function(text) {
    if (text === headers.get('Accept')) {
      parent.postMessage('PASS', '*');
    } else {
      parent.postMessage('custom accept FAIL - expected ' + headers.get('Accept') +
                         ' got "' + text + '"', '*');
    }
  }).catch(function(err) {
    parent.postMessage('custom accept FAIL - unexpected error: ' + err, '*');
  });

  // Check for default accept header
  fetch(uri).then(function(response) {
    return response.text();
  }).then(function(text) {
    if (text === '*/*') {
      parent.postMessage('PASS', '*');
    } else {
      parent.postMessage('accept FAIL - expected */* got "' + text + '"', '*');
    }
  }).catch(function(err) {
    parent.postMessage('accept FAIL - unexpected error: ' + err, '*');
  });
</script>


text:
package com.freetymekiyan.algorithms.level.medium;

import java.util.Arrays;

/**
 * 300. Longest Increasing Subsequence
 *

 * Given an unsorted array of integers, find the length of longest increasing subsequence.
 *

 * For example,
 * Given [10, 9, 2, 5, 3, 7, 101, 18],
 * The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there may be more than one
 * LIS combination, it is only necessary for you to return the length.
 *

 * Your algorithm should run in O(n^2) complexity.
 *

 * Follow up: Could you improve it to O(nlogn) time complexity?
 *

 * Tags: Dynamic Programming, Binary Search
 * Similar Problems: (M) Increasing Triplet Subsequence, (H) Russian Doll Envelopes
 */
public class LongestIncreasingSubsequence {

    /**
     * DP. O(nlogn) time. O(n) space.
     * Store the tail of a LIS at a specific length.
     * dp[0] means the tail value of array at length 1.
     * Current number can either replace an existing tail value, or expand the whole LIS because it's the largest.
     * Binary search for the insertion point of current number.
     * Update the number at the position.
     * If the insertion point equal to the current size, it means the number is the largest.
     * Increment the length of LIS by 1.
     */
    public int lengthOfLIS(int[] nums) {
        int[] tails = new int[nums.length];
        int len = 0;
        for (int n : nums) {
            int l = 0; // Binary search for the insertion position.
            int r = len;
            while (l < r) {
                int m = l + (r - l) / 2;
                if (tails[m] < n) {
                    l = m + 1;
                } else {
                    r = m;
                }
            }
            tails[l] = n; // Update the tail value. l is the insertion position.
            if (l == len) { // n is the largest.
                len++;
            }
        }
        return len;
    }

    /**
     * DP. O(n^2) time, O(n) space.
     * We can store the longest increasing subseqence lengths of [0, i-1].
     * Now at index i, if nums[i] is larger than nums[x], it can form a longer LIS.
     * So dp[i] = max(dp[x] + 1), x in [0, i-1].
     * If nums[i] is smaller or equal to nums[x], then nums[i] cannot form a longer LIS.
     * So dp[i] = 1.
     * The longest is the maximum of the dp array.
     */
    public int lengthOfLIS2(int[] nums) {
        int[] dp = new int[nums.length];
        Arrays.fill(dp, 1);
        int max = nums.length > 0 ? 1 : 0;
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j  nums[j]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
            max = Math.max(dp[i], max);
        }
        return max;
    }
}

redpajama_set_name: RedPajamaGithub


text:
<?php

namespace backend\models;

use yii\base\Model;
use yii\data\ActiveDataProvider;

/**
 * Plb3QuestionSearch represents the model behind the search form about `backend\models\Plb3Question`.
 */
class Plb3QuestionSearch extends Plb3Question
{
    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['id'], 'integer'],
            [['plb3_question_type_code', 'plb3_question'], 'safe'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function scenarios()
    {
        // bypass scenarios() implementation in the parent class
        return Model::scenarios();
    }

    /**
     * Creates data provider instance with search query applied
     *
     * @param array $params
     *
     * @return ActiveDataProvider
     */
    public function search($params)
    {
        $query = Plb3Question::find();

        // add conditions that should always apply here

        $dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);

        $this->load($params);

        if (!$this->validate()) {
            // uncomment the following line if you do not want to return any records when validation fails
            // $query->where('0=1');
            return $dataProvider;
        }

        // grid filtering conditions
        $query->andFilterWhere([
            'id' => $this->id,
        ]);

        $query->andFilterWhere(['like', 'plb3_form_type_code', $this->plb3_form_type_code])
            ->andFilterWhere(['like', 'plb3_question_type_code', $this->plb3_question_type_code])
            ->andFilterWhere(['like', 'plb3_question', $this->plb3_question]);

        return $dataProvider;
    }
}


text:
package bos.whu.familytree.model;

/**
 * Created by Consoar on 2015/3/27.
 */
public class PersonBean {
    private long gid = 0;
    private long pid = 0;
    private long ggen = 0;
    private String photourl = null;
    private String  pdetail = "";
    private String firstname = "";
    private String fullname = "";
    private String birthday = "";
    private String bornplace = "";
    private String borndsc = "";
    private int islive = 1;
    private String deathday = "";
    private String deathplace = "";
    private String graveyard = "";
    private String deathdsc = "";
    private int sex = 1; //0未知  1男 2女
    private long wifeID = 0;
    private long fatherID = 0;
    private long motherID = 0;
    private PersonBean wife = null;
    private PersonBean father = null;
    private PersonBean mother = null;

    public long getGid() {
        return gid;
    }
    public void setGid(long gid) {
        this.gid = gid;
    }
    public long getPid() {
        return pid;
    }
    public void setPid(long pid) {
        this.pid = pid;
    }
    public long getGgen() {
        return ggen;
    }
    public void setGgen(long ggen) {
        this.ggen = ggen;
    }
    public String getPhotourl() {
        return photourl;
    }
    public void setPhotourl(String photourl) {
        this.photourl = photourl;
    }
    public String getPdetail() {
        return pdetail;
    }
    public void setPdetail(String pdetail) {
        this.pdetail = pdetail;
    }
    public String getFirstname() {
        return firstname;
    }
    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }
    public String getFullname() {
        return fullname;
    }
    public void setFullname(String fullname) {
        this.fullname = fullname;
    }
    public String getBirthday() {
        return birthday;
    }
    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }
    public String getBornplace() {
        return bornplace;
    }
    public void setBornplace(String bornplace) {
        this.bornplace = bornplace;
    }
    public String getBorndsc() {
        return borndsc;
    }
    public void setBorndsc(String borndsc) {
        this.borndsc = borndsc;
    }
    public int getIslive() {
        return islive;
    }
    public void setIslive(int islive) {
        this.islive = islive;
    }
    public String getDeathday() {
        return deathday;
    }
    public void setDeathday(String deathday) {
        this.deathday = deathday;
    }
    public String getDeathplace() {
        return deathplace;
    }
    public void setDeathplace(String deathplace) {
        this.deathplace = deathplace;
    }
    public String getGraveyard() {
        return graveyard;
    }
    public void setGraveyard(String graveyard) {
        this.graveyard = graveyard;
    }
    public String getDeathdsc() {
        return deathdsc;
    }
    public void setDeathdsc(String deathdsc) {
        this.deathdsc = deathdsc;
    }
    public int getSex() {
        return sex;
    }
    public void setSex(int sex) {
        this.sex = sex;
    }
    public long getWifeID() {
        return wifeID;
    }
    public void setWifeID(long wifeID) {
        this.wifeID = wifeID;
    }
    public long getFatherID() {
        return fatherID;
    }
    public void setFatherID(long fatherID) {
        this.fatherID = fatherID;
    }
    public long getMotherID() {
        return motherID;
    }
    public void setMotherID(long motherID) {
        this.motherID = motherID;
    }
    public PersonBean getWife() {
        return wife;
    }
    public void setWife(PersonBean wife) {
        this.wife = wife;
    }
    public PersonBean getFather() {
        return father;
    }
    public void setFather(PersonBean father) {
        this.father = father;
    }
    public PersonBean getMother() {
        return mother;
    }
    public void setMother(PersonBean mother) {
        this.mother = mother;
    }

    @Override
    public String toString() {
        return "PersonBean{" +
                "gid=" + gid +
                ", pid=" + pid +
                ", ggen=" + ggen +
                ", photourl='" + photourl + '\'' +
                ", pdetail='" + pdetail + '\'' +
                ", firstname='" + firstname + '\'' +
                ", fullname='" + fullname + '\'' +
                ", birthday='" + birthday + '\'' +
                ", bornplace='" + bornplace + '\'' +
                ", borndsc='" + borndsc + '\'' +
                ", islive=" + islive +
                ", deathday='" + deathday + '\'' +
                ", deathplace='" + deathplace + '\'' +
                ", graveyard='" + graveyard + '\'' +
                ", deathdsc='" + deathdsc + '\'' +
                ", sex=" + sex +
                ", wifeID=" + wifeID +
                ", fatherID=" + fatherID +
                ", motherID=" + motherID +
                '}';
    }
}


text:
package org.apache.activemq.artemis.jms.tests.message;

import javax.jms.Message;

import org.apache.activemq.artemis.jms.tests.util.ProxyAssertSupport;
import org.junit.Test;

public class JMSCorrelationIDHeaderTest extends MessageHeaderTestBase {
   // Constants -----------------------------------------------------

   // Static --------------------------------------------------------

   // Attributes ----------------------------------------------------

   // Constructors --------------------------------------------------

   // Public --------------------------------------------------------

   @Test
   public void testJMSDestination() throws Exception {
      Message m1 = queueProducerSession.createMessage();

      // Test with correlation id containing a message id
      final String messageID = "ID:812739812378";
      m1.setJMSCorrelationID(messageID);

      queueProducer.send(m1);
      Message m2 = queueConsumer.receive();
      ProxyAssertSupport.assertEquals(messageID, m2.getJMSCorrelationID());

      // Test with correlation id containing an application defined string
      Message m3 = queueProducerSession.createMessage();
      final String appDefinedID = "oiwedjiwjdoiwejdoiwjd";
      m3.setJMSCorrelationID(appDefinedID);

      queueProducer.send(m3);
      Message m4 = queueConsumer.receive();
      ProxyAssertSupport.assertEquals(appDefinedID, m4.getJMSCorrelationID());

      // Test with correlation id containing a byte[]
      Message m5 = queueProducerSession.createMessage();
      final byte[] bytes = new byte[]{-111, 45, 106, 3, -44};
      m5.setJMSCorrelationIDAsBytes(bytes);

      queueProducer.send(m5);
      Message m6 = queueConsumer.receive();
      assertByteArraysEqual(bytes, m6.getJMSCorrelationIDAsBytes());

   }

   // Package protected ---------------------------------------------

   // Protected -----------------------------------------------------

   // Private -------------------------------------------------------

   private void assertByteArraysEqual(final byte[] bytes1, final byte[] bytes2) {
      if (bytes1 == null | bytes2 == null) {
         ProxyAssertSupport.fail();
      }

      if (bytes1.length != bytes2.length) {
         ProxyAssertSupport.fail();
      }

      for (int i = 0; i < bytes1.length; i++) {
         ProxyAssertSupport.assertEquals(bytes1[i], bytes2[i]);
      }

   }

   // Inner classes -------------------------------------------------

}


text:
//Copyright (c) 2015, David Larochelle-Pratte
//All rights reserved.
//
//        Redistribution and use in source and binary forms, with or without
//        modification, are permitted provided that the following conditions are met:
//
//        1. Redistributions of source code must retain the above copyright notice, this
//        list of conditions and the following disclaimer.
//        2. 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.
//
//        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, STRICT 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.
package com.hancinworld.fw.proxy;

import com.hancinworld.fw.handler.ConfigurationHandler;
import com.hancinworld.fw.handler.DrawScreenEventHandler;
import com.hancinworld.fw.handler.KeyInputEventHandler;
import com.hancinworld.fw.reference.Reference;
import com.hancinworld.fw.utility.LogHelper;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.client.SplashProgress;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.KeyBinding;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;

import java.awt.*;
import java.io.File;

public class ClientProxy extends CommonProxy {

    private final Minecraft client = Minecraft.getMinecraft();
    private Rectangle _savedWindowedBounds;
    public static boolean fullscreen;
    public static KeyBinding fullscreenKeyBinding;
    public DrawScreenEventHandler dsHandler;

    /** This keybind replaces the default MC fullscreen keybind in their logic handler. Without it, the game crashes.
     *  If this is set to any valid key, problems may occur. */
    public static KeyBinding ignoreKeyBinding = new KeyBinding("key.fullscreenwindowed.unused", Keyboard.KEY_NONE, "key.categories.misc");

    public ClientProxy()
    {
    }

    @Override
    public void registerKeyBindings()
    {
        /* FIXME: Overrides the minecraft hotkey for fullscreen, as there are no hooks */
        if(fullscreenKeyBinding == null && ConfigurationHandler.instance().isFullscreenWindowedEnabled())
        {
            fullscreenKeyBinding = client.gameSettings.keyBindFullscreen;
            client.gameSettings.keyBindFullscreen = ignoreKeyBinding;

        }
        else if(fullscreenKeyBinding != null && !ConfigurationHandler.instance().isFullscreenWindowedEnabled())
        {
            Minecraft mc = Minecraft.getMinecraft();
            mc.gameSettings.keyBindFullscreen = fullscreenKeyBinding;
            fullscreenKeyBinding = null;

            if(fullscreen){
                mc.fullscreen = false;
                mc.toggleFullscreen();
            }
        }
    }

    @Override
    public void subscribeEvents(File configurationFile) {

        ConfigurationHandler.instance().init(configurationFile);
        FMLCommonHandler.instance().bus().register(ConfigurationHandler.instance());
        FMLCommonHandler.instance().bus().register(new KeyInputEventHandler());
        dsHandler = new DrawScreenEventHandler();
        MinecraftForge.EVENT_BUS.register(dsHandler);
    }

    private Rectangle findCurrentScreenDimensionsAndPosition(int x, int y)
    {
        GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice[] screens = env.getScreenDevices();

        for(GraphicsDevice dev : screens)
        {
            GraphicsConfiguration displayMode = dev.getDefaultConfiguration();
            Rectangle bounds = displayMode.getBounds();

            if(bounds.contains(x, y))
                return bounds;
        }

        //if Java isn't able to find a matching screen then use the old LWJGL calcs.
        return new Rectangle(0, 0, Display.getDesktopDisplayMode().getWidth(), Display.getDesktopDisplayMode().getHeight());
}
    private Rectangle findScreenDimensionsByID(int monitorID)
    {
        if(monitorID < 1)
            return null;

        GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice[] screens = env.getScreenDevices();

        if(screens == null || screens.length == 0 || screens.length < monitorID){
            return null;
        }

        return screens[monitorID - 1].getDefaultConfiguration().getBounds();
    }

    private Rectangle getAppropriateScreenBounds(Rectangle currentCoordinates, int desiredMonitor)
    {
        Rectangle screenBounds;
        Point centerCoordinates = new Point((int) (currentCoordinates.getMinX() + currentCoordinates.getWidth() / 2), (int) (currentCoordinates.getMinY() + currentCoordinates.getHeight() / 2));

        ConfigurationHandler configuration = ConfigurationHandler.instance();
        //First feature mode: Only remove decorations. No need to calculate screen positions, we're not changing size or location.
        if(configuration.areAdvancedFeaturesEnabled() && configuration.isOnlyRemoveDecorations()){
            screenBounds = currentCoordinates;
        }
        //Custom dimensions enabled: follow requested settings if we can work with them.
        else if(configuration.areAdvancedFeaturesEnabled() && configuration.isCustomFullscreenDimensions() && (configuration.getCustomFullscreenDimensionsH() > 256 && configuration.getCustomFullscreenDimensionsW() > 256))
        {
            screenBounds = new Rectangle(configuration.getCustomFullscreenDimensionsX(),configuration.getCustomFullscreenDimensionsY(), configuration.getCustomFullscreenDimensionsW(),configuration.getCustomFullscreenDimensionsH());

            //If you've selected a monitor, then X & Y are offsets - easier to do math.
            if(desiredMonitor > 0) {
                Rectangle actualScreenBounds = findScreenDimensionsByID(desiredMonitor);
                if(actualScreenBounds != null){
                    screenBounds.setLocation(actualScreenBounds.x + screenBounds.x, actualScreenBounds.y + screenBounds.y);
                }
            }
        }
        // No specified monitor for fullscreen -> find the one the window is on right now
        else if(desiredMonitor < 0 || desiredMonitor == Reference.AUTOMATIC_MONITOR_SELECTION) {
            //find which monitor we should be using based on the center of the MC window
            screenBounds = findCurrentScreenDimensionsAndPosition((int) centerCoordinates.getX(), (int) centerCoordinates.getY());
        // specified monitor for fullscreen -> get dimensions.
        }else{
            screenBounds = findScreenDimensionsByID(desiredMonitor);
            // you've specified a monitor but it doesn't look connected. Revert to automatic mode.
            if(screenBounds == null){
                screenBounds = findCurrentScreenDimensionsAndPosition((int) centerCoordinates.getX(), (int) centerCoordinates.getY());
            }
        }

        return screenBounds;
    }
    @Override
    public void toggleFullScreen(boolean goFullScreen) {
        toggleFullScreen(goFullScreen, ConfigurationHandler.instance().getFullscreenMonitor());
    }

    @Override
    public void toggleFullScreen(boolean goFullScreen, int desiredMonitor) {

        //Set value if it isn't set already.
        if(System.getProperty("org.lwjgl.opengl.Window.undecorated") == null){
            System.setProperty("org.lwjgl.opengl.Window.undecorated", "false");
        }

        //If we're in actual fullscreen right now, then we need to fix that.
        if(Display.isFullscreen()) {
            fullscreen = true;
        }

        String expectedState = goFullScreen ? "true":"false";
        // If all state is valid, there is nothing to do and we just exit.
        if(fullscreen == goFullScreen
                && !Display.isFullscreen()//Display in fullscreen mode: Change required
                && System.getProperty("org.lwjgl.opengl.Window.undecorated") == expectedState // Window not in expected state
        )
            return;

        //Save our current display parameters
        Rectangle currentCoordinates = new Rectangle(Display.getX(), Display.getY(), Display.getWidth(), Display.getHeight());
        if(goFullScreen && !Display.isFullscreen())
            _savedWindowedBounds = currentCoordinates;

        //Changing this property and causing a Display update will cause LWJGL to add/remove decorations (borderless).
        System.setProperty("org.lwjgl.opengl.Window.undecorated",expectedState);

        //Get the fullscreen dimensions for the appropriate screen.
        Rectangle screenBounds = getAppropriateScreenBounds(currentCoordinates, desiredMonitor);

        //This is the new bounds we have to apply.
        Rectangle newBounds = goFullScreen ? screenBounds : _savedWindowedBounds;
        if(newBounds == null)
            newBounds = screenBounds;

        if(goFullScreen == false && ClientProxy.fullscreen == false) {
            newBounds = currentCoordinates;
            _savedWindowedBounds = currentCoordinates;
        }

        try {
            fullscreen = goFullScreen;
            client.fullscreen = fullscreen;
            if( client.gameSettings.fullScreen != fullscreen) {
                client.gameSettings.fullScreen = fullscreen;
                client.gameSettings.saveOptions();
            }
            Display.setFullscreen(false);
            Display.setResizable(!goFullScreen);
            Display.setDisplayMode(new DisplayMode((int) newBounds.getWidth(), (int) newBounds.getHeight()));
            Display.setLocation(newBounds.x, newBounds.y);

            client.resize((int) newBounds.getWidth(), (int) newBounds.getHeight());
            Display.setVSyncEnabled(client.gameSettings.enableVsync);
            client.updateDisplay();

        } catch (LWJGLException e) {
            e.printStackTrace();
        }

    }

    @Override
    @SuppressWarnings("deprecated")
    public void performStartupChecks()
    {
        //If the mod is disabled by configuration, just put back the initial value.
        if(!ConfigurationHandler.instance().isFullscreenWindowedEnabled()) {
            return;
        }

        if(ConfigurationHandler.instance().isMaximumCompatibilityEnabled()){
            dsHandler.setInitialFullscreen(client.gameSettings.fullScreen,  ConfigurationHandler.instance().getFullscreenMonitor());
        // This is the correct way to set fullscreen at launch, but LWJGL limitations means we might crash the game if
        // another mod tries to do a similar Display changing operation. Doesn't help the API says "don't use this"
        }else{
            try {
                //FIXME: Living dangerously here... Is there a better way of doing this?
                SplashProgress.pause();
                toggleFullScreen(client.gameSettings.fullScreen, ConfigurationHandler.instance().getFullscreenMonitor());
                SplashProgress.resume();
            }catch(NoClassDefFoundError e) {
                LogHelper.warn("Error while doing startup checks, are you using an old version of Forge ? " + e);
                toggleFullScreen(client.gameSettings.fullScreen, ConfigurationHandler.instance().getFullscreenMonitor());
            }
        }
    }
}


text:
name: Bug report
about: Create a report to help us improve

---

## Problem

Description of problem here.

- [ ] I checked the issue tracker for existing issues about this problem.
- [ ] I'm using the latest version of intero.
- [ ] I am not using Nix, which is notorious for breaking stack, intero and lots of other things.
- [ ] I have checked that my error is not GHC's fault by testing my project on standard GHCi.
- [ ] I am using calm, polite language.
- [ ] I am not trying to use intero on bleeding edge GHC (head or nightly); Intero is only developed against full GHC releases.

### Input program/project

Link to sample project here. It helps to paste something on
https://gist.github.com/

* If the problem occurs on any Haskell file, you can just paste a small sample Haskell file.
* If the problem occurs on a specific type of project, plase consider pasting all your stack.yaml, proj.cabal and any relevant .hs files into the Gist too.

That way, a maintainer can easily clone down your test case and reproduce the behavior. Issues that the maintainers can't reproduce **will probably not get fixed**.

If you pressed specific Emacs keypresses, what were they? It also helps to enable debugging in Emacs with `M-x intero-toggle-debug` which will print a log of everything in `*Messages*`, which you can include in the "Actual behavior" section below in a gist.

### Expected behavior

Describe what you expected.

### Actual behavior

What actually happened. Include any https://gist.github.com/ links of output logs. Don't fill the issue description with output. :+1+

### Workarounds

Feel free to include any workarounds that might help other people until the issue is fixed.


text:
/*
    Site Project Layout Styles
    Author: seoul2045
    Filename: site_project_layout.css
*/

/* * { /*this is great for troubleshooting and you can use other elements in place of * asterik
    outline: 1px solid red;
}
*/

body {

}

/*
nav {
    width: 175px;
    float: left;
    margin-right: 15px;
}
*/


text:
// Copyright 2017 DAIMTO ([Linda Lawton](https://twitter.com/LindaLawtonDK)) :  [www.daimto.com](http://www.daimto.com/)
//
// 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.
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by DAIMTO-Google-apis-Sample-generator 1.0.0
//     Template File Name:  methodTemplate.tt
//     Build date: 2017-10-08
//     C# generater version: 1.0.0
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
// About
//
// Unoffical sample for the Taskqueue v1beta2 API for C#.
// This sample is designed to be used with the Google .Net client library. (https://github.com/google/google-api-dotnet-client)
//
// API Description: Accesses a Google App Engine Pull Task Queue over REST.
// API Documentation Link https://developers.google.com/appengine/docs/python/taskqueue/rest
//
// Discovery Doc  https://www.googleapis.com/discovery/v1/apis/Taskqueue/v1beta2/rest
//
//------------------------------------------------------------------------------
// Installation
//
// This sample code uses the Google .Net client library (https://github.com/google/google-api-dotnet-client)
//
// NuGet package:
//
// Location: https://www.nuget.org/packages/Google.Apis.Taskqueue.v1beta2/
// Install Command: PM>  Install-Package Google.Apis.Taskqueue.v1beta2
//
//------------------------------------------------------------------------------
using Google.Apis.Taskqueue.v1beta2;
using Google.Apis.Taskqueue.v1beta2.Data;
using System;

namespace GoogleSamplecSharpSample.Taskqueuev1beta2.Methods
{

    public static class TaskqueuesSample
    {

        public class TaskqueuesGetOptionalParms
        {
            /// Whether to get stats. Optional.
            public bool? GetStats { get; set; }

        }

        /// <summary>
        /// Get detailed information about a TaskQueue.
        /// Documentation https://developers.google.com/taskqueue/v1beta2/reference/taskqueues/get
        /// Generation Note: This does not always build corectly.  Google needs to standardise things I need to figuer out which ones are wrong.
        /// </summary>
        /// <param name="service">Authenticated Taskqueue service.</param>
        /// <param name="project">The project under which the queue lies.</param>
        /// <param name="taskqueue">The id of the taskqueue to get the properties of.</param>
        /// <param name="optional">Optional paramaters.</param>
        /// <returns>TaskQueueResponse</returns>
        public static TaskQueue Get(TaskqueueService service, string project, string taskqueue, TaskqueuesGetOptionalParms optional = null)
        {
            try
            {
                // Initial validation.
                if (service == null)
                    throw new ArgumentNullException("service");
                if (project == null)
                    throw new ArgumentNullException(project);
                if (taskqueue == null)
                    throw new ArgumentNullException(taskqueue);

                // Building the initial request.
                var request = service.Taskqueues.Get(project, taskqueue);

                // Applying optional parameters to the request.
                request = (TaskqueuesResource.GetRequest)SampleHelpers.ApplyOptionalParms(request, optional);

                // Requesting data.
                return request.Execute();
            }
            catch (Exception ex)
            {
                throw new Exception("Request Taskqueues.Get failed.", ex);
            }
        }

        }

        public static class SampleHelpers
        {

        /// <summary>
        /// Using reflection to apply optional parameters to the request.
        ///
        /// If the optonal parameters are null then we will just return the request as is.
        /// </summary>
        /// <param name="request">The request. </param>
        /// <param name="optional">The optional parameters. </param>
        /// <returns></returns>
        public static object ApplyOptionalParms(object request, object optional)
        {
            if (optional == null)
                return request;

            System.Reflection.PropertyInfo[] optionalProperties = (optional.GetType()).GetProperties();

            foreach (System.Reflection.PropertyInfo property in optionalProperties)
            {
                // Copy value from optional parms to the request.  They should have the same names and datatypes.
                System.Reflection.PropertyInfo piShared = (request.GetType()).GetProperty(property.Name);
				if (property.GetValue(optional, null) != null) // TODO Test that we do not add values for items that are null
					piShared.SetValue(request, property.GetValue(optional, null), null);
            }

            return request;
        }
    }
}


text:
namespace chainerx {

Scalar AsScalar(const Array& a) {
    if (a.GetTotalSize() != 1) {
        throw DimensionError{"Cannot convert an array of size ", a.GetTotalSize(), " to a scalar, size must be 1."};
    }

    // Copy to the native device
    Array native_copy = a.ToNative();

    // Retrieve the value
    return VisitDtype(a.dtype(), [&native_copy](auto pt) -> Scalar {
        using T = typename decltype(pt)::type;
        const uint8_t* ptr = static_cast<const uint8_t*>(native_copy.data().get()) + native_copy.offset();
        auto typed_ptr = reinterpret_cast<const T*>(ptr);  // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
        return Scalar{*typed_ptr};
    });
}

Array RollAxis(const Array& a, int8_t axis, int8_t start) {
    // TODO(hvy): Optimize the implementation.
    axis = internal::NormalizeAxis(axis, a.ndim());

    // start can be a.ndim() so we cannot use NormalizeAxis here.
    if (start < -a.ndim() || start > a.ndim()) {
        throw DimensionError{"start arg out of bounds. start: ", start, ", ndim: ", a.ndim()};
    }
    if (start < 0) {
        start += a.ndim();
    }

    Axes axes;
    for (int8_t i = 0; i < a.ndim(); ++i) {
        if (i == start) {
            axes.emplace_back(axis);
        }
        if (i != axis) {
            axes.emplace_back(i);
        }
    }
    if (start == a.ndim()) {
        axes.emplace_back(axis);
    }
    return Transpose(a, axes);
}

Array Transpose(const Array& a, const OptionalAxes& axes) {
    Axes real_axes;
    if (axes.has_value()) {
        if (axes->ndim() != a.ndim()) {
            throw DimensionError{"Axes do not match, input array dimensions: ", a.ndim(), " but axes: ", axes->ndim()};
        }
        real_axes = internal::GetNormalizedAxes(*axes, a.ndim());
    } else {
        for (int8_t i = 0; i < a.ndim(); ++i) {
            real_axes.emplace_back(a.ndim() - i - 1);
        }
    }
    CHAINERX_ASSERT(real_axes.ndim() == a.ndim());

    Shape out_shape;
    Strides out_strides;
    for (int8_t axis : real_axes) {
        out_shape.emplace_back(a.shape()[axis]);
        out_strides.emplace_back(a.strides()[axis]);
    }

    Array out = internal::MakeArray(out_shape, out_strides, a.dtype(), a.device(), a.data(), a.offset());

    BackwardBuilder bb{"transpose", a, out};
    if (BackwardBuilder::Target bt = bb.CreateTarget(0)) {
        bt.Define([real_axes](BackwardContext& bctx) {
            Axes backward_axes;
            backward_axes.resize(real_axes.ndim());
            for (int8_t i = 0; i < real_axes.ndim(); ++i) {
                backward_axes[real_axes[i]] = i;
            }
            bctx.input_grad() = bctx.output_grad()->Transpose(backward_axes);
        });
    }
    bb.Finalize();

    return out;
}

namespace {

// Returns a shape where the length of at most one dimension is inferred from the total size and the remaining dimensions.
// Such a dimension is given by a negative length, i.e. Shape{2, 3, -1}.
// If the given shape does not contain such a dimension, this function will return a copy of the given shape.
// If there exists multiple negative lengths or if the negative length dimension cannot be inferred due to non divisbility, an
// DimensionError is thrown.
Shape GetInferredShape(const Shape& shape, int64_t total_size) {
    Shape inferred_shape = shape;

    auto it = std::find_if(inferred_shape.begin(), inferred_shape.end(), [](int64_t dim) { return dim < 0; });
    if (it != inferred_shape.end()) {
        if (std::find_if(std::next(it), inferred_shape.end(), [](int64_t dim) { return dim < 0; }) != inferred_shape.end()) {
            throw DimensionError{"Can only specify one unknown dimension"};
        }
        int64_t rest_size = std::accumulate(inferred_shape.begin(), it, int64_t{1}, std::multiplies<>()) *
                            std::accumulate(std::next(it), inferred_shape.end(), int64_t{1}, std::multiplies<>());
        *it = total_size / rest_size;
    }

    if (total_size != inferred_shape.GetTotalSize()) {
        throw DimensionError{"Cannot reshape array of size ", total_size, " into shape ", shape};
    }
    return inferred_shape;
}

}  // namespace

Array Reshape(const Array& a, const Shape& newshape) {
    const Shape& in_shape = a.shape();
    const Strides& in_strides = a.strides();

    // If the shape is unchanged, just return a view.
    if (in_shape == newshape) {
        return a.MakeView();
    }

    // Check for invalid shape.
    int64_t total_size = in_shape.GetTotalSize();
    Shape out_shape = GetInferredShape(newshape, total_size);
    int64_t item_size = a.GetItemSize();
    Strides strides{};
    if (total_size == 0) {
        // Calculate the strides for 0-sized array.
        strides.resize(out_shape.ndim());
        strides.back() = item_size;
        for (int8_t i = out_shape.ndim() - 1; i >= 1; --i) {
            strides[i - 1] = strides[i] * std::max(int64_t{1}, out_shape[i]);
        }
    } else {
        // Calculate the strides for non-0-sized array.

        // reduced_shape and reduced_strides are the shortest shape and strides which can be convertible from input shape and strides
        // without copy.
        Shape reduced_shape{};
        Strides reduced_strides{};
        if (total_size == 1) {
            reduced_shape.emplace_back(int64_t{1});
            reduced_strides.emplace_back(item_size);
        } else {
            int8_t i = 0;
            // Ignore preceding 1-length dimensions
            while (i < in_shape.ndim() && in_shape[i] == 1) {
                ++i;
            }
            // Add the first pair
            reduced_shape.emplace_back(in_shape[i]);
            reduced_strides.emplace_back(in_strides[i]);
            ++i;
            // Reduce the remaining
            for (; i < in_shape.ndim(); ++i) {
                int64_t dim = in_shape[i];
                int64_t st = in_strides[i];
                CHAINERX_ASSERT(dim > 0);
                if (dim == 1 && st == 0) {
                    // If the axis has unit-length with no stride, skip this dimension.
                } else if (dim * st == reduced_strides.back()) {
                    // If the pair is compatible with the previous stride, reduce the pair to it.
                    reduced_shape.back() *= dim;
                    reduced_strides.back() = st;
                } else {
                    // Otherwise, add a new shape and stride.
                    reduced_shape.emplace_back(dim);
                    reduced_strides.emplace_back(st);
                }
            }
        }
        CHAINERX_ASSERT(reduced_shape.size() == reduced_strides.size());
        CHAINERX_ASSERT(!reduced_shape.empty());

        // Construct the strides for no-copy reshape.
        // If it's not possible, can_reshape_without_copy will be false.
        bool can_reshape_without_copy = true;
        if (out_shape.ndim() > 0) {
            int64_t last_stride = reduced_shape[0] * reduced_strides[0];
            size_t i_dim = 0;
            for (int64_t dim : out_shape) {
                if (dim <= 1) {
                    strides.emplace_back(last_stride);
                    continue;
                }
                if (i_dim >= reduced_shape.size() || reduced_shape[i_dim] % dim != 0) {
                    strides.clear();
                    can_reshape_without_copy = false;
                    break;
                }
                reduced_shape[i_dim] /= dim;
                last_stride = reduced_shape[i_dim] * reduced_strides[i_dim];
                strides.emplace_back(last_stride);
                if (reduced_shape[i_dim] == 1) {
                    ++i_dim;
                }
            }
        }

        if (!can_reshape_without_copy) {
            // Copy is required.
            return a.Copy().Reshape(out_shape);
        }
        CHAINERX_ASSERT(strides.size() == out_shape.size());
    }

    Array out = internal::MakeArray(out_shape, strides, a.dtype(), a.device(), a.data(), a.offset());

    BackwardBuilder bb{"reshape", a, out};
    if (BackwardBuilder::Target bt = bb.CreateTarget(0)) {
        bt.Define([in_shape](BackwardContext& bctx) { bctx.input_grad() = bctx.output_grad()->Reshape(in_shape); });
    }
    bb.Finalize();

    CHAINERX_ASSERT(out.shape() == out_shape);
    CHAINERX_ASSERT(out.strides().size() == out_shape.size());
    return out;
}

Array Squeeze(const Array& a, const OptionalAxes& axis) {
    const Shape& in_shape = a.shape();
    const Strides& in_strides = a.strides();

    Shape out_shape{};
    Strides out_strides{};

    if (axis.has_value()) {
        const Axes sorted_axis = internal::GetSortedAxes(*axis, in_shape.ndim());

        int64_t i_axis = 0;
        for (int64_t i = 0; i < in_shape.ndim(); ++i) {
            if (i_axis < static_cast<int64_t>(sorted_axis.size()) && sorted_axis[i_axis] == i) {
                ++i_axis;
                if (in_shape[i] != 1) {
                    std::ostringstream os;
                    os << "Cannot squeeze out non-unit-length axes, where shape was " << in_shape.ToString();
                    os << " and axes were (";
                    for (auto it = axis->begin(); it != axis->end(); ++it) {
                        if (it != axis->begin()) {
                            os << ", ";
                        }
                        os << *it;
                    }
                    os << (axis->size() == 1 ? ",)." : ").");
                    throw DimensionError{os.str()};
                }
            } else {
                out_shape.emplace_back(in_shape[i]);
                out_strides.emplace_back(in_strides[i]);
            }
        }
    } else {  // All axes are candidates for removal if none are given.
        for (int64_t i = 0; i < in_shape.ndim(); ++i) {
            if (in_shape[i] != 1) {
                out_shape.emplace_back(in_shape[i]);
                out_strides.emplace_back(in_strides[i]);
            }
        }
    }

    if (in_shape.size() == out_shape.size()) {
        return a;
    }

    Array out = internal::MakeArray(out_shape, out_strides, a.dtype(), a.device(), a.data(), a.offset());

    BackwardBuilder bb{"squeeze", a, out};
    if (BackwardBuilder::Target bt = bb.CreateTarget(0)) {
        bt.Define([in_shape](BackwardContext& bctx) { bctx.input_grad() = bctx.output_grad()->Reshape(in_shape); });
    }
    bb.Finalize();

    return out;
}

Array BroadcastTo(const Array& array, const Shape& shape) {
    const Shape& in_shape = array.shape();
    const Strides& in_strides = array.strides();

    if (in_shape.size() > shape.size()) {
        throw DimensionError{"Cannot broadcast to smaller dimensions from ", in_shape, " to ", shape, "."};
    }

    // Compute the new set of strides after broadcastining.
    Strides strides;
    strides.resize(shape.ndim());
    int8_t i_in = in_shape.ndim() - 1;
    for (int8_t i_out = shape.ndim() - 1; i_out >= 0; --i_out) {
        int64_t out_dim = shape[i_out];
        // If this dimension is to be broadcasted, nonbroadcast_stride is unset.
        // Otherwise, it holds the new stride.
        nonstd::optional<int64_t> nonbroadcast_stride{};
        if (i_in >= 0) {
            int64_t in_dim = in_shape[i_in];
            if (in_dim == 1) {
                // do nothing; broadcast
            } else if (in_dim == out_dim) {
                nonbroadcast_stride = in_strides[i_in];
            } else {
                throw DimensionError{"Invalid broadcast from ", in_shape, " to ", shape};
            }
            --i_in;
        } else {
            // do nothing; broadcast
        }

        if (nonbroadcast_stride.has_value()) {
            // non-broadcast dimension
            strides[i_out] = nonbroadcast_stride.value();
        } else {
            // broadcast dimension
            strides[i_out] = int64_t{0};
        }
    }
    CHAINERX_ASSERT(i_in == -1);
    CHAINERX_ASSERT(strides.ndim() == shape.ndim());

    Array out = internal::MakeArray(shape, strides, array.dtype(), array.device(), array.data(), array.offset());

    BackwardBuilder bb{"broadcast_to", array, out};
    if (BackwardBuilder::Target bt = bb.CreateTarget(0)) {
        bt.Define([in_shape](BackwardContext& bctx) {
            const Array& gout = *bctx.output_grad();
            if (gout.shape() == in_shape) {
                bctx.input_grad() = gout;
                return;
            }

            int8_t lead = gout.ndim() - in_shape.ndim();
            Axes lead_axis{};
            lead_axis.resize(lead);
            std::iota(lead_axis.begin(), lead_axis.end(), int8_t{0});

            Axes axis{lead_axis};
            for (int8_t i = 0; i < in_shape.ndim(); ++i) {
                if (in_shape[i] == 1) {
                    axis.emplace_back(i + lead);
                }
            }
            axis.erase(std::unique(axis.begin(), axis.end()), axis.end());  // Sum does not accept axis with duplicate elements

            Array gin = gout.Sum(axis, true);
            if (lead > 0) {
                bctx.input_grad() = gin.Squeeze(lead_axis);
            } else {
                bctx.input_grad() = std::move(gin);
            }
        });
    }
    bb.Finalize();

    return out;
}

namespace {

Array ConcatenateImpl(const std::vector<Array>& arrays, int8_t axis) {
    if (arrays.empty()) {
        throw DimensionError{"Need at least one array to concatenate"};
    }

    Shape shape = arrays.front().shape();
    Dtype dtype = arrays.front().dtype();
    Device& device = arrays.front().device();
    int8_t ndim = arrays.front().ndim();
    axis = internal::NormalizeAxis(axis, ndim);
    shape[axis] = 0;
    std::vector<int64_t> indices;
    indices.reserve(arrays.size() - 1);

    for (const Array& array : arrays) {
        const Shape& s = array.shape();
        if (ndim != array.ndim()) {
            throw DimensionError{"All the input arrays must have same number of dimensions"};
        }
        // TODO(imanishi): dtype conversion
        CheckEqual(dtype, array.dtype());
        for (int8_t i = 0; i < ndim; ++i) {
            if (axis == i) {
                shape[i] += s[i];
            } else if (shape[i] != s[i]) {
                throw DimensionError{"All the input array dimensions except for the concatenation axis must match exactly"};
            }
        }
        if (indices.size() < arrays.size() - 1) {
            indices.emplace_back(shape[axis]);
        }
    }

    Strides strides{shape, dtype};

    // Aligning with NumPy strides behavior
    auto last_zero_it = std::find(shape.rbegin(), shape.rend(), int64_t{0});
    if (last_zero_it != shape.rend()) {
        std::fill(strides.rbegin() + (last_zero_it - shape.rbegin() + 1), strides.rend(), int64_t{0});
    }

    Array out = internal::Empty(shape, dtype, strides, device);
    {
        NoBackpropModeScope scope{};
        int64_t out_offset = 0;
        for (const Array& array : arrays) {
            const Shape& shape = array.shape();
            Array sliced_out = internal::MakeArray(shape, strides, dtype, device, out.data(), out_offset);
            device.Copy(array, sliced_out);
            out_offset += strides[axis] * shape[axis];
        }
    }

    std::vector<ConstArrayRef> array_refs;
    array_refs.reserve(arrays.size());
    std::transform(arrays.begin(), arrays.end(), std::back_inserter(array_refs), [](const Array& array) { return ConstArrayRef{array}; });

    {
        BackwardBuilder bb{"concatenate", array_refs, out};
        if (BackwardBuilder::Target bt = bb.CreateTarget()) {
            bt.Define([indices = std::move(indices), axis](BackwardContext& bctx) {
                std::vector<Array> gxs = Split(*bctx.output_grad(), indices, axis);
                for (size_t i = 0; i < gxs.size(); ++i) {
                    bctx.input_grad(i) = std::move(gxs[i]);
                }
            });
        }
        bb.Finalize();
    }

    return out;
}

}  // namespace

Array Concatenate(const std::vector<Array>& arrays) { return ConcatenateImpl(arrays, 0); }

Array Concatenate(const std::vector<Array>& arrays, nonstd::optional<int8_t> axis) {
    if (axis.has_value()) {
        return ConcatenateImpl(arrays, *axis);
    }
    std::vector<Array> raveled_arrays;
    raveled_arrays.reserve(arrays.size());
    std::transform(arrays.begin(), arrays.end(), std::back_inserter(raveled_arrays), [](const Array& array) {
        Shape shape{array.GetTotalSize()};
        return array.Reshape(shape);
    });
    return ConcatenateImpl(raveled_arrays, 0);
}

namespace {
std::vector<Array> StackGrad(const Array& gout, int8_t axis) {
    Shape shape{gout.shape()};
    Strides strides{gout.strides()};
    size_t dim = shape[axis];
    int64_t step = strides[axis];
    shape.erase(shape.begin() + axis);
    strides.erase(strides.begin() + axis);

    std::vector<Array> gxs;
    std::vector<ConstArrayRef> gxs_refs{};
    gxs.reserve(dim);
    gxs_refs.reserve(dim);
    {
        NoBackpropModeScope scope{};
        Dtype dtype = gout.dtype();
        Device& device = gout.device();
        for (size_t i = 0; i < dim; ++i) {
            gxs.emplace_back(internal::MakeArray(shape, strides, dtype, device, gout.data(), step * i));
            gxs_refs.emplace_back(gxs.back());
        }
    }

    {
        BackwardBuilder bb{"stack-grad", gout, gxs_refs};
        if (BackwardBuilder::Target bt = bb.CreateTarget()) {
            bt.Define([axis](BackwardContext& bctx) {
                std::vector<Array> ggxs;
                ggxs.reserve(bctx.output_count());
                for (size_t i = 0; i < bctx.output_count(); ++i) {
                    // TODO(imanishi): Check if bctx.output_grad(i) is not nullopt.
                    ggxs.emplace_back(*bctx.output_grad(i));
                }
                bctx.input_grad() = Stack(ggxs, axis);
            });
        }
        bb.Finalize();
    }
    return gxs;
}
}  // namespace

Array Stack(const std::vector<Array>& arrays, int8_t axis) {
    if (arrays.empty()) {
        throw DimensionError{"Need at least one array to stack"};
    }

    Shape shape = arrays.front().shape();
    Dtype dtype = arrays.front().dtype();
    Device& device = arrays.front().device();
    uint8_t ndim = shape.ndim();
    axis = internal::NormalizeAxis(axis, ndim + 1);

    for (const Array& array : arrays) {
        if (shape != array.shape()) {
            throw DimensionError{"All input arrays must have the same shape"};
        }
        // TODO(imanishi): dtype conversion
        CheckEqual(dtype, array.dtype());
    }
    shape.insert(shape.begin() + axis, static_cast<int64_t>(arrays.size()));

    Strides strides{shape, dtype};

    // Aligning with NumPy strides behavior
    auto last_zero_it = std::find(shape.rbegin(), shape.rend(), int64_t{0});
    if (last_zero_it != shape.rend()) {
        std::fill(strides.rbegin() + (last_zero_it - shape.rbegin() + 1), strides.rend(), int64_t{0});
    }

    Array out = internal::Empty(shape, dtype, strides, device);

    int64_t step = strides[axis];
    strides.erase(strides.begin() + axis);
    {
        NoBackpropModeScope scope{};
        int64_t out_offset = 0;
        for (const Array& array : arrays) {
            Array sliced_out = internal::MakeArray(array.shape(), strides, dtype, device, out.data(), out_offset);
            device.Copy(array, sliced_out);
            out_offset += step;
        }
    }

    std::vector<ConstArrayRef> array_refs;
    array_refs.reserve(arrays.size());
    std::transform(arrays.begin(), arrays.end(), std::back_inserter(array_refs), [](const Array& array) { return ConstArrayRef{array}; });

    {
        BackwardBuilder bb{"stack", array_refs, out};
        if (BackwardBuilder::Target bt = bb.CreateTarget()) {
            bt.Define([axis](BackwardContext& bctx) {
                const Array& gout = *bctx.output_grad();
                std::vector<Array> gxs = StackGrad(gout, axis);
                for (size_t i = 0; i < gxs.size(); ++i) {
                    bctx.input_grad(i) = gxs[i];
                }
            });
        }
        bb.Finalize();
    }

    return out;
}

namespace {

// Defines the backward pass for Split, for both by-sections and by-indices.
void DefineSplitBackward(const Array& ary, const std::vector<Array>& out, int8_t axis_norm) {
    // TODO(hvy): Avoid creating an intermediate vector of reference when BackwardBuilder accepts std::vector<Array>.
    std::vector<ConstArrayRef> out_refs{};
    out_refs.reserve(out.size());
    std::transform(out.begin(), out.end(), std::back_inserter(out_refs), [](const Array& array) { return ConstArrayRef{array}; });

    // TODO(imanishi): Avoid creating shapes of forward outputs;
    std::vector<Shape> shapes;
    shapes.reserve(out.size());
    std::transform(out.begin(), out.end(), std::back_inserter(shapes), [](const Array& array) { return array.shape(); });

    BackwardBuilder bb{"split", ary, out_refs};
    if (BackwardBuilder::Target bt = bb.CreateTarget(0)) {
        bt.Define([axis_norm, shapes = std::move(shapes), dtype = ary.dtype(), &device = ary.device()](BackwardContext& bctx) {
            std::vector<Array> output_grads;
            output_grads.reserve(bctx.output_count());
            for (size_t i = 0; i < bctx.output_count(); ++i) {
                const nonstd::optional<Array>& gy = bctx.output_grad(i);
                output_grads.emplace_back(gy.has_value() ? *gy : Zeros(shapes[i], dtype, device));
            }
            bctx.input_grad() = ConcatenateImpl(output_grads, axis_norm);
        });
    }
    bb.Finalize();
}

}  // namespace

std::vector<Array> Split(const Array& ary, int64_t sections, int8_t axis) {
    if (sections < 1) {
        throw DimensionError("Number of sections must be larger than 0.");
    }

    const Shape& in_shape = ary.shape();
    int8_t axis_norm = internal::NormalizeAxis(axis, ary.ndim());
    int64_t in_dim = in_shape[axis_norm];

    if (in_dim % sections != 0) {
        throw DimensionError("Array split does not result in an equal division.");
    }

    Shape out_shape = in_shape;
    int64_t out_dim = in_dim / sections;
    out_shape[axis_norm] = out_dim;
    int64_t out_stride = ary.strides()[axis_norm];
    int64_t out_offset = ary.offset();

    std::vector<Array> out{};
    out.reserve(sections);

    for (int64_t i = 0; i < sections; ++i) {
        out.emplace_back(internal::MakeArray(out_shape, ary.strides(), ary.dtype(), ary.device(), ary.data(), out_offset));
        out_offset += out_stride * out_dim;
    }

    DefineSplitBackward(ary, out, axis_norm);

    return out;
}

std::vector<Array> Split(const Array& ary, std::vector<int64_t> indices, int8_t axis) {
    const Shape& in_shape = ary.shape();
    int8_t axis_norm = internal::NormalizeAxis(axis, ary.ndim());
    int64_t in_dim = in_shape[axis_norm];

    // Wrap negative indices.
    std::transform(
            indices.begin(), indices.end(), indices.begin(), [in_dim](int64_t index) { return index >= 0 ? index : index + in_dim; });
    indices.emplace_back(in_dim);

    Shape out_shape = in_shape;
    int64_t out_stride = ary.strides()[axis_norm];
    int64_t out_offset = ary.offset();
    int64_t slice_start = 0;

    std::vector<Array> out{};
    out.reserve(indices.size());

    for (int64_t index : indices) {
        int64_t slice_stop = std::min(in_dim, std::max(int64_t{0}, index));
        int64_t slice_step = slice_stop - slice_start;

        // Update the dimension of interest in the output shape.
        out_shape[axis_norm] = std::max(int64_t{0}, slice_step);

        out.emplace_back(internal::MakeArray(out_shape, ary.strides(), ary.dtype(), ary.device(), ary.data(), out_offset));

        out_offset += out_stride * slice_step;
        slice_start = slice_stop;
    }

    DefineSplitBackward(ary, out, axis_norm);

    return out;
}

}  // namespace chainerx


text:
module CacheKeyForHelper
  def cache_key_for(scoped_collection, collection_prefix, cache_owner_cache_key = '', suffix = '', whitelist_params = [], default_params = {})
    # 1) paginated scope - `maximum/max` database query on page(2) does not work
    # 2) Array doesn't respond to `total_pages`
    max_updated_at = if scoped_collection.respond_to?(:total_pages) || scoped_collection.class == Array
      scoped_collection.to_a.map { |i| i.updated_at ? i.updated_at.utc.to_f : 0 }.max
    elsif scoped_collection.respond_to?(:maximum) # not paginated ActiveRecord::Relation
      begin
        scoped_collection.maximum(scoped_collection.table_name + '.updated_at').to_f
      # can't use join table as query root if query includes polimorphic associations
      rescue ActiveRecord::EagerLoadPolymorphicError
        Rails.logger.debug "[CacheKeyForHelper] Fallback to array (ActiveRecord::EagerLoadPolymorphicError)"
        scoped_collection = scoped_collection.to_a
        scoped_collection.to_a.map { |i| i.updated_at ? i.updated_at.utc.to_f : 0 }.max
      end
    elsif scoped_collection.respond_to?(:max) # not paginated Mongoid::Criteria
      scoped_collection.max(:updated_at).to_f
    end
    count = if scoped_collection.respond_to?(:total_count) # kaminari
      scoped_collection.total_count
    elsif scoped_collection.respond_to?(:total_entries) # will_paginate
      scoped_collection.total_entries
    else # Array or not paginated scope
      scoped_collection.count
    end
    ids_string = if scoped_collection.respond_to?(:ids)
      begin
        scoped_collection.ids
      rescue ActiveRecord::EagerLoadPolymorphicError
        Rails.logger.debug "[CacheKeyForHelper] Fallback to array (ActiveRecord::EagerLoadPolymorphicError)"
        scoped_collection.to_a.map(&:id).join('-')
      end
    else
      scoped_collection.to_a.map(&:id).join('-')
    end
    blacklist_params = ['utm_source', 'utm_medium', 'utm_term', 'utm_content', 'utm_campaign']
    flat_request_params = if request.params
      if whitelist_params.empty?
        default_params.stringify_keys.merge(request.params).reject { |k, _v| blacklist_params.map(&:to_s).include?(k) }
      else
        default_params.stringify_keys.merge(request.params).select { |k, _v| whitelist_params.map(&:to_s).include?(k) }
      end.map { |k, v|
        # don't care about data type in the `v`, convert all to string
        [k.to_s.dup.force_encoding('UTF-8'), v.to_s.dup.force_encoding('UTF-8')]
      }.to_h
    else
      nil
    end
    digest = Digest::SHA1.hexdigest("#{ids_string}-#{max_updated_at}-#{count}-#{request.subdomains.join('.')}-#{request.path}-#{flat_request_params}")
    # puts "Caller: #{caller.first}"
    # puts "generated cache key digest base: #{ids_string}-#{max_updated_at}-#{count}-#{request.subdomains.join('.')}-#{request.path}-#{flat_request_params}"
    # puts "generated cache key: #{I18n.locale}/#{collection_prefix}/#{digest}/#{cache_owner_cache_key}/#{suffix}"
    "#{I18n.locale}/#{collection_prefix}/#{digest}/#{cache_owner_cache_key}/#{suffix}"
  end
end


text:
<?php

namespace {

    use ForceLabs\Framework\Application;
    use ForceLabs\Framework\Config\Config;
    use ForceLabs\Framework\Debug\BasicException;

    // define some basic stuff
    error_reporting(E_ALL);
    define('APP_DEBUG', true);

    $filePath = dirname(__FILE__).DIRECTORY_SEPARATOR;

    if(!defined('BASE_PATH')) {
        define('BASE_PATH', $filePath);
    }

    date_default_timezone_set('UTC');

    // include composer autoloader
    if (file_exists($filePath.'vendor/autoload.php')) {
        require $filePath.'vendor/autoload.php';
    } else {
        die('Required libraries not found!');
    }

    // initialize the Application class
    $app = Application::initialize(BASE_PATH, APP_DEBUG);

    // set the exception handler
    set_exception_handler(function ($e) use ($app) {
        if (defined('CONSOLE') && CONSOLE) {
            BasicException::catchConsoleException($e, $app);
        } else {
            BasicException::catchException($e, $app);
        }
    });

    // register the Application itself
    $app->singleton(Application::class, $app);

    // check if the runtime path exists
    if (!is_dir($app->runtimePath())) {
        mkdir($app->runtimePath());
        chmod($app->runtimePath(), 0777);
    }

    // register PSR-4 class loading
    $app->register();
    $app->loadConfigs('database', 'event', 'namespace', 'commands');

    // register namespaces
    foreach ($app->make(Config::class)['namespace'] as $namespace => $path) {
        $app->addNamespace($namespace, $path);
    }

    // run startup scripts
    if (file_exists($app->configPath().'startup.php')) {
        require $app->configPath().'startup.php';
    }

    return $app;
}


text:
module FormtasticValidation

  NAMESPACE = 'validation'
  @@valid_message = "Thank you!"
  mattr_accessor :valid_message

  def self.included(base)
    base.class_eval {
      alias_method_chain :input, :validation
    }
  end

  def input_with_validation(method, options = {})
    if has_validations?(method)
      options[:input_html] = validation_tags(method, options[:input_html])
    end
    input_without_validation(method, options)
  end

  def has_validations?(attribute)
    if @object && @object.class.respond_to?(:reflect_on_validations_for)
      @object.class.reflect_on_validations_for(attribute_sym(attribute)).present?
    else
      false
    end
  end

  def attribute_sym(attribute)
    attribute.to_s.sub(/_id$/, '').to_sym
  end

  def validation_tags(attribute, input_html)
    tags = []
    @object.class.reflect_on_validations_for(attribute).each do |validation|
      tags << { :validation => validation.macro }.merge(validation.options.merge(validation_valid_message_tag))
    end
    stack_tags(tags, input_html)
  end

  def validation_valid_message_tag
    { :valid_message => @@valid_message }
  end

  def stack_tags(tags, input_html)
    vtags = validates_tags(tags.dup)
    otags = options_tags(tags.dup)
    if input_html
      input_html[:validation] = vtags
      input_html.merge(otags)
    else
      { :validation => vtags }.merge(otags)
    end
  end

  def validates_tags(tags)
    validates_tags = tags.map { |tag| tag[:validation] }
    validates_tags.join(' ')
  end

  def options_tags(tags)
    otags_array = tags.map do |tag|
      tag.delete_if { |key, value| key.eql?(:validation) }
    end
    opts_hash = otags_array.inject { |memo, hash| memo.merge(hash) }
    namespaced_hash = add_namespace(opts_hash)
    serialise_options(namespaced_hash)
  end

  def add_namespace(opts_hash)
    namespaced_hash = Hash.new
    opts_hash.each do |key, value|
      namespaced_key = (NAMESPACE + '_' + key.to_s).to_sym
      namespaced_hash[namespaced_key] = value
    end
    namespaced_hash
  end

  def serialise_options(opts_hash)
    serialised_hash = Hash.new
    opts_hash.each do |key, value|
      serialised_value = case value.class.to_s
                         when "String" then value
                         when "Regexp" then value.inspect
                         else value.to_json
                         end
      serialised_hash[key] = serialised_value
    end
    serialised_hash
  end

end


text:
package rescala.extra.lattices.delta.crdt.basic

import kofre.decompose.DotStore.DotSet
import kofre.decompose.interfaces.EWFlagInterface
import kofre.decompose.interfaces.EWFlagInterface.{EWFlagCompanion, State}
import kofre.decompose.{UIJDLattice}

import rescala.extra.replication.AntiEntropy

/** [[BasicCRDT Basic]] implementation of [[rescala.extra.lattices.delta.interfaces.EWFlagInterface EWFlagInterface]]
  *
  * Instead of the class constructor, you should use the apply method of the companion object to create new instances.
  *
  * @tparam C Type of the causal context used for this Causal CRDT
  */
class EWFlag(
    val state: State,
    protected val antiEntropy: AntiEntropy[State]
) extends EWFlagInterface[EWFlag] with BasicCRDT[State, EWFlag] {

  override protected def copy(state: State): EWFlag = new EWFlag(state, antiEntropy)
}

object EWFlag extends EWFlagCompanion {

  /** Creates a new EWFlag instance
    *
    * @param antiEntropy AntiEntropy instance used for exchanging deltas with other replicas
    * @tparam C Type of the causal context used for this Causal CRDT
    */
  def apply(antiEntropy: AntiEntropy[State]): EWFlag =
    new EWFlag(UIJDLattice[State].bottom, antiEntropy)
}


text:
import * as React from "react"
import { Box, BoxProps, Image, ResponsiveBox, Text } from "@artsy/palette"
import { createFragmentContainer, graphql } from "react-relay"
import styled from "styled-components"
import { RouterLink } from "v2/System/Router/RouterLink"
import { FairsFairBanner_fair } from "v2/__generated__/FairsFairBanner_fair.graphql"

const Overlay = styled(Box)`
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  display: flex;
  align-items: flex-end;
  background-color: rgba(0, 0, 0, 0.5);
  opacity: 0;
  transition: opacity 250ms;

  > div {
    transition: transform 250ms;
    transform: translateY(25%);
  }

  &:hover {
    opacity: 1;

    > div {
      transform: translateY(0);
    }
  }
`

interface FairsFairBannerProps extends BoxProps {
  fair: FairsFairBanner_fair
}

const FairsFairBanner: React.FC<FairsFairBannerProps> = ({ fair, ...rest }) => {
  const banner =
    fair.image &&
    (fair.bannerSize === "x-large" ? fair.image.large : fair.image.small)

  const icon = fair?.profile?.icon?.resized

  return (
    <Box {...rest}>
      <RouterLink
        to={fair.href}
        display="block"
        textDecoration="none"
        aria-label={`Go to ${fair.name}`}
      >
        {banner && (
          <ResponsiveBox
            position="relative"
            aspectWidth={banner.width}
            aspectHeight={banner.height}
            maxWidth="100%"
            borderRadius={2}
            overflow="hidden"
          >
            <Image
              width="100%"
              height="100%"
              src={banner.src}
              srcSet={banner.srcSet}
              alt=""
              lazyLoad
            />

            <Overlay>
              <Text variant="lg" m={4} color="white100">
                Explore the event
              </Text>
            </Overlay>
          </ResponsiveBox>
        )}

        <Box display="flex" alignItems="center" mt={1}>
          {icon && (
            <Box mr={2}>
              <Image
                width={icon.width}
                height={icon.height}
                src={icon.src}
                srcSet={icon.srcSet}
                alt={`Logo of ${fair.name}`}
              />
            </Box>
          )}

          <Box>
            <Text>{fair.name}</Text>

            <Text>{fair.exhibitionPeriod}</Text>
          </Box>
        </Box>
      </RouterLink>
    </Box>
  )
}

export const FairsFairBannerFragmentContainer = createFragmentContainer(
  FairsFairBanner,
  {
    fair: graphql`
      fragment FairsFairBanner_fair on Fair {
        href
        name
        exhibitionPeriod
        bannerSize
        image {
          large: cropped(width: 1840, height: 790, version: ["wide"]) {
            src
            srcSet
            width
            height
          }
          small: cropped(width: 910, height: 512, version: ["wide"]) {
            src
            srcSet
            width
            height
          }
        }
        profile {
          icon {
            resized(width: 80, height: 80, version: "square140") {
              width
              height
              src
              srcSet
            }
          }
        }
      }
    `,
  }
)


text:
use std;
use serde_json;
use std::io::prelude::*;
use std::net::{ToSocketAddrs, UdpSocket};
use std::hash::{Hash, Hasher};
use std::collections::hash_map::DefaultHasher;
use log::{Log, LogLevel, LogMetadata, LogRecord};
use flate2::Compression;
use flate2::write::GzEncoder;
use chrono::{DateTime, UTC};
use byteorder::{BigEndian, WriteBytesExt};

use GraylogError;

const MAX_PACKET_SIZE: usize = 8192;
const MAGIC_BYTES: u16 = 0x1E0F;
const HEADER_SIZE: usize = 12; // TODO: figure out how to do this with mem::size_of<ChunkHeader>()

struct GraylogLogger<A: ToSocketAddrs> {
    server: A,
    sock: UdpSocket,
    level: LogLevel,
    hostname: String,
}

#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Gelf {
    version: String,
    host: String,
    short_message: String,
    full_message: Option<String>,
    timestamp: Option<i64>,
    level: Option<u8>,
    #[serde(rename="_file")]
    file: String,
    #[serde(rename="_line")]
    line: u32,
}

struct GelfChunks<'a> {
    count: usize,
    total: usize,
    #[allow(dead_code)]
    data: &'a [u8],
    chunks: Vec<&'a [u8]>,
    message_id: u64,
}

struct Chunk<'a> {
    header: ChunkHeader,
    data: &'a [u8],
}

impl<'a> Chunk<'a> {
    fn to_binary(&self) -> Result<Vec<u8>, GraylogError> {
        let mut wrt = vec![];
        try!(wrt.write_u16::<BigEndian>(self.header.magic_bytes));
        try!(wrt.write_u64::<BigEndian>(self.header.message_id));
        try!(wrt.write_u8(self.header.seq_number));
        try!(wrt.write_u8(self.header.seq_count));
        wrt.extend_from_slice(self.data);
        Ok(wrt)
    }
}

#[derive(Debug)]
struct ChunkHeader {
    magic_bytes: u16,
    message_id: u64,
    seq_number: u8,
    seq_count: u8,
}

impl<'a> GelfChunks<'a> {
    fn new(data: &'a [u8], message_id: u64) -> GelfChunks<'a> {
        let chunk_size = MAX_PACKET_SIZE - HEADER_SIZE;
        let mut chunks = data.chunks(chunk_size).collect::<Vec<&[u8]>>();
        chunks.reverse();

        GelfChunks {
            count: 0,
            total: chunks.len(),
            chunks: chunks,
            data: data,
            message_id: message_id,
        }
    }
}

impl<'a> Iterator for GelfChunks<'a> {
    type Item = Chunk<'a>;

    fn next(&mut self) -> Option<Chunk<'a>> {
        self.chunks.pop().map(|data| {
            let header = ChunkHeader {
                magic_bytes: MAGIC_BYTES,
                message_id: self.message_id,
                seq_number: self.count as u8,
                seq_count: self.total as u8,
            };
            println!("{:?}", header);

            self.count += 1;

            Chunk {
                header: header,
                data: data,
            }
        })
    }
}

pub fn init<A: ToSocketAddrs + 'static>(addr: A, level: LogLevel) -> Result<(), GraylogError>
    where A: std::marker::Send + std::marker::Sync
{
    use log;
    use std::process::Command;
    let sock = try!(UdpSocket::bind("0.0.0.0:0"));

    try!(log::set_logger(|max_log_level| {
        max_log_level.set(level.to_log_level_filter());
        let hostname = Command::new("hostname")
            .arg("-f")
            .output()
            .map(|out| String::from_utf8_lossy(&out.stdout).into_owned())
            .unwrap_or("unknown".to_string());

        Box::new(GraylogLogger {
            level: level,
            server: addr,
            sock: sock,
            hostname: hostname.trim().to_string(),
        })
    }));
    Ok(())
}

impl Gelf {
    fn message_id(&self) -> u64 {
        use chrono::Timelike;
        let mut s = DefaultHasher::new();
        self.host.hash(&mut s);
        self.timestamp.hash(&mut s);
        UTC::now().nanosecond().hash(&mut s);
        s.finish()
    }
}

impl<A: ToSocketAddrs> GraylogLogger<A> {
    fn send_as_gelf(&self, record: &LogRecord) -> Result<usize, GraylogError> {
        let utc: DateTime<UTC> = UTC::now();

        let location = record.location();
        let gelf = Gelf {
            version: "1.1".to_string(),
            short_message: format!("{}", record.args()),
            full_message: None,
            timestamp: Some(utc.timestamp()),
            level: None,
            host: self.hostname.clone(),
            file: location.file().to_string(),
            line: location.line(),
        };

        let json = try!(serde_json::to_string(&gelf));
        let mut e = GzEncoder::new(Vec::new(), Compression::Default);
        try!(e.write_all(json.as_bytes()));

        let compressed_bytes = try!(e.finish());
        if compressed_bytes.len() > MAX_PACKET_SIZE {
            self.send_chunked_gelf(&compressed_bytes, gelf.message_id())
        } else {
            self.send(&compressed_bytes)
        }
    }

    fn send_chunked_gelf(&self, buffer: &[u8], message_id: u64) -> Result<usize, GraylogError> {
        let chunks = GelfChunks::new(buffer, message_id);
        println!("Graylog message_id: {:x}", message_id);
        for chunk in chunks {
            let data = try!(chunk.to_binary());
            try!(self.send(&data));
        }
        Ok(1)
    }

    fn send(&self, buffer: &[u8]) -> Result<usize, GraylogError> {
        let s = try!(self.sock.send_to(buffer, &self.server).or_else(|e| {
            println!("Error writing to Graylog: {}", e);
            Err(e)
        }));
        Ok(s)
    }
}

impl<A: ToSocketAddrs> Log for GraylogLogger<A>
    where A: std::marker::Send + std::marker::Sync
{
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= self.level
    }

    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) && self.send_as_gelf(record).is_err() {
            println!("{} {} - {}", UTC::now(), record.level(), record.args());
        }
    }
}

#[test]
fn test_gelf_serialization() {
    use serde_json::Value;
    let file = "asdfasdfadsf.rs".to_string();
    let line = 123;
    let gelf = Gelf {
        version: "1.1".to_string(),
        host: "somehost".to_string(),
        short_message: "some short message".to_string(),
        full_message: Some("Full message".to_string()),
        timestamp: Some(UTC::now().timestamp()),
        level: None,
        file: file.clone(),
        line: line,
    };
    let json = serde_json::to_string(&gelf).unwrap();
    println!("Json\n{}", json);

    let data: Value = serde_json::from_str(&json).unwrap();
    let obj = data.as_object().unwrap();
    assert_eq!(obj.get("_file").unwrap().as_str().unwrap(), file);
    assert_eq!(obj.get("_line").unwrap().as_u64().unwrap(), line as u64);

    let deserialized_gelf: Gelf = serde_json::from_str(&json).unwrap();
    assert_eq!(deserialized_gelf, gelf);
    println!("{:?}", obj);
}

#[cfg(test)]
mod tests {
    use log;

    use super::*;

    #[test]
    fn test_it_works() {
        assert!(init("192.168.1.1", log::LogLevel::Debug).is_ok());
    }

}


text:
package org.hope6537.note.design.command.example;

/**
 * 具体的接受类
 */
public class RevicerImpl1 extends Receiver {
    @Override
    public void doSomething() {

    }
}


text:
package verify

import (
	"context"
	"fmt"

	"github.com/golang/glog"
	"github.com/google/trillian-examples/clone/logdb"
	"github.com/transparency-dev/merkle/compact"
)

// LeafHashFn returns the leaf hash (commitment) to the given preimage at the given log index.
type LeafHashFn func(index uint64, data []byte) []byte

// NewLogVerifier returns a LogVerifier which obtains raw leaves from `db`, and uses the given
// hash functions to construct a merkle tree.
func NewLogVerifier(db *logdb.Database, lh LeafHashFn, ih compact.HashFn) LogVerifier {
	return LogVerifier{
		db: db,
		lh: lh,
		rf: &compact.RangeFactory{Hash: ih},
	}
}

// LogVerifier calculates the Merkle root of a log.
type LogVerifier struct {
	db *logdb.Database
	lh LeafHashFn
	rf *compact.RangeFactory
}

// MerkleRoot calculates the Merkle root hash of its log at the given size.
func (v LogVerifier) MerkleRoot(ctx context.Context, size uint64) ([]byte, [][]byte, error) {
	cr := v.rf.NewEmptyRange(0)
	from := uint64(0)

	if cpSize, _, crBs, err := v.db.GetLatestCheckpoint(ctx); err != nil {
		if err != logdb.ErrNoDataFound {
			return nil, nil, err
		}
	} else if size >= cpSize {
		from = cpSize
		cr, err = v.rf.NewRange(0, cpSize, crBs)
		if err != nil {
			return nil, nil, err
		}
	}

	leaves := make(chan []byte, 1)
	errc := make(chan error)
	glog.V(1).Infof("Streaming leaves [%d, %d)", from, size)
	go v.db.StreamLeaves(from, size, leaves, errc)

	index := from
	for leaf := range leaves {
		select {
		case err := <-errc:
			return nil, nil, fmt.Errorf("failed to get leaves from DB: %w", err)
		default:
		}
		cr.Append(v.lh(index, leaf), nil)
		index++
	}
	if index != size {
		return nil, nil, fmt.Errorf("expected to receive %d leaves but got %d", size, index)
	}
	root, err := cr.GetRootHash(nil)
	return root, cr.Hashes(), err
}