text:
package org.apache.hadoop.hdfs.server.datanode;

import io.hops.leader_election.node.ActiveNode;
import io.hops.leader_election.node.SortedActiveNodeList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.impl.Log4JLogger;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.CommonConfigurationKeys;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FileUtil;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.DFSConfigKeys;
import org.apache.hadoop.hdfs.DFSTestUtil;
import org.apache.hadoop.hdfs.DistributedFileSystem;
import org.apache.hadoop.hdfs.HdfsConfiguration;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.hdfs.MiniDFSNNTopology;
import org.apache.hadoop.hdfs.protocol.DatanodeID;
import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
import org.apache.hadoop.hdfs.protocol.ExtendedBlock;
import org.apache.hadoop.hdfs.protocol.LocatedBlock;
import org.apache.hadoop.hdfs.protocol.RecoveryInProgressException;
import org.apache.hadoop.hdfs.protocolPB.DatanodeProtocolClientSideTranslatorPB;
import org.apache.hadoop.hdfs.server.common.HdfsServerConstants.ReplicaState;
import org.apache.hadoop.hdfs.server.datanode.DataNode.BlockRecord;
import org.apache.hadoop.hdfs.server.datanode.fsdataset.ReplicaOutputStreams;
import org.apache.hadoop.hdfs.server.namenode.FSNamesystem;
import org.apache.hadoop.hdfs.server.protocol.BlockRecoveryCommand.RecoveringBlock;
import org.apache.hadoop.hdfs.server.protocol.DatanodeCommand;
import org.apache.hadoop.hdfs.server.protocol.DatanodeProtocol;
import org.apache.hadoop.hdfs.server.protocol.DatanodeRegistration;
import org.apache.hadoop.hdfs.server.protocol.HeartbeatResponse;
import org.apache.hadoop.hdfs.server.protocol.InterDatanodeProtocol;
import org.apache.hadoop.hdfs.server.protocol.NamespaceInfo;
import org.apache.hadoop.hdfs.server.protocol.ReplicaRecoveryInfo;
import org.apache.hadoop.hdfs.server.protocol.StorageReport;
import org.apache.hadoop.test.GenericTestUtils;
import org.apache.hadoop.util.Daemon;
import org.apache.hadoop.util.DataChecksum;
import org.apache.log4j.Level;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyListOf;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

/**
 * This tests if sync all replicas in block recovery works correctly
 */
public class TestBlockRecovery {
  private static final Log LOG = LogFactory.getLog(TestBlockRecovery.class);
  private static final String DATA_DIR =
      MiniDFSCluster.getBaseDirectory() + "data";
  private DataNode dn;
  private Configuration conf;
  private final static long RECOVERY_ID = 3000L;
  private final static String CLUSTER_ID = "testClusterID";
  private final static String POOL_ID = "BP-TEST";
  private final static InetSocketAddress NN_ADDR =
      new InetSocketAddress("localhost", 5020);
  private final static long BLOCK_ID = 1000L;
  private final static long GEN_STAMP = 2000L;
  private final static long BLOCK_LEN = 3000L;
  private final static long REPLICA_LEN1 = 6000L;
  private final static long REPLICA_LEN2 = 5000L;
  private final static ExtendedBlock block =
      new ExtendedBlock(POOL_ID, BLOCK_ID, BLOCK_LEN, GEN_STAMP);

  static {
    ((Log4JLogger) LogFactory.getLog(FSNamesystem.class)).getLogger()
        .setLevel(Level.ALL);
    ((Log4JLogger) LOG).getLogger().setLevel(Level.ALL);
  }

  /**
   * Starts an instance of DataNode
   *
   * @throws IOException
   */
  @Before
  public void startUp() throws IOException {
    conf = new HdfsConfiguration();
    conf.set(DFSConfigKeys.DFS_DATANODE_DATA_DIR_KEY, DATA_DIR);
    conf.set(DFSConfigKeys.DFS_DATANODE_ADDRESS_KEY, "0.0.0.0:0");
    conf.set(DFSConfigKeys.DFS_DATANODE_HTTP_ADDRESS_KEY, "0.0.0.0:0");
    conf.set(DFSConfigKeys.DFS_DATANODE_IPC_ADDRESS_KEY, "0.0.0.0:0");
    conf.setInt(CommonConfigurationKeys.IPC_CLIENT_CONNECT_MAX_RETRIES_KEY, 0);
    FileSystem.setDefaultUri(conf,
        "hdfs://" + NN_ADDR.getHostName() + ":" + NN_ADDR.getPort());
    ArrayList<File> dirs = new ArrayList<File>();
    File dataDir = new File(DATA_DIR);
    FileUtil.fullyDelete(dataDir);
    dataDir.mkdirs();
    dirs.add(dataDir);
    final DatanodeProtocolClientSideTranslatorPB namenode =
        mock(DatanodeProtocolClientSideTranslatorPB.class);

    Mockito.doAnswer(new Answer<DatanodeRegistration>() {
      @Override
      public DatanodeRegistration answer(InvocationOnMock invocation)
          throws Throwable {
        return (DatanodeRegistration) invocation.getArguments()[0];
      }
    }).when(namenode).registerDatanode(Mockito.any(DatanodeRegistration.class));

    when(namenode.versionRequest())
        .thenReturn(new NamespaceInfo(1, CLUSTER_ID, POOL_ID, 1L));

    when(namenode.sendHeartbeat(Mockito.any(DatanodeRegistration.class),
        Mockito.any(StorageReport[].class), Mockito.anyInt(), Mockito.anyInt(),
        Mockito.anyInt()))
        .thenReturn(new HeartbeatResponse(new DatanodeCommand[0]));

    when(namenode.getActiveNamenodes()).thenReturn(new SortedActiveNodeList() {
      @Override
      public boolean isEmpty() {
        return true;
      }

      @Override
      public int size() {
        return 0;
      }

      @Override
      public List<ActiveNode> getActiveNodes() {
        return new ArrayList<ActiveNode>();
      }

      @Override
      public List<ActiveNode> getSortedActiveNodes() {
        return null;
      }

      @Override
      public ActiveNode getActiveNode(InetSocketAddress address) {
        return null;
      }

      @Override
      public ActiveNode getLeader() {
        return null;
      }
    });

    dn = new DataNode(conf, dirs, null) {
      @Override
      DatanodeProtocolClientSideTranslatorPB connectToNN(
          InetSocketAddress nnAddr) throws IOException {
        Assert.assertEquals(NN_ADDR, nnAddr);
        return namenode;
      }

      @Override
      public DatanodeProtocolClientSideTranslatorPB getActiveNamenodeForBP(
          String bpid) throws IOException {
        return namenode;
      }
    };

    BPOfferService bpos = dn.getAllBpOs()[0];
    BPServiceActor bpsa = bpos.getBPServiceActors().get(0);
    bpsa.bpNamenode = namenode;
    NamespaceInfo nsInfo = bpsa.retrieveNamespaceInfo();
    bpos.verifyAndSetNamespaceInfo(nsInfo);
    bpos.bpRegistration = bpos.createRegistration();

    // Trigger a heartbeat so that it acknowledges the NN as active.
    dn.getAllBpOs()[0].triggerHeartbeatForTests();
  }

  /**
   * Cleans the resources and closes the instance of datanode
   *
   * @throws IOException
   *     if an error occurred
   */
  @After
  public void tearDown() throws IOException {
    if (dn != null) {
      try {
        dn.shutdown();
      } catch (Exception e) {
        LOG.error("Cannot close: ", e);
      } finally {
        File dir = new File(DATA_DIR);
        if (dir.exists()) {
          Assert.assertTrue("Cannot delete data-node dirs",
              FileUtil.fullyDelete(dir));
        }
      }
    }
  }

  /**
   * Sync two replicas
   */
  private void testSyncReplicas(ReplicaRecoveryInfo replica1,
      ReplicaRecoveryInfo replica2, InterDatanodeProtocol dn1,
      InterDatanodeProtocol dn2, long expectLen) throws IOException {

    DatanodeInfo[] locs =
        new DatanodeInfo[]{mock(DatanodeInfo.class), mock(DatanodeInfo.class)};
    RecoveringBlock rBlock = new RecoveringBlock(block, locs, RECOVERY_ID);
    ArrayList<BlockRecord> syncList = new ArrayList<BlockRecord>(2);
    BlockRecord record1 =
        new BlockRecord(DFSTestUtil.getDatanodeInfo("1.2.3.4", "bogus", 1234),
            dn1, replica1);
    BlockRecord record2 =
        new BlockRecord(DFSTestUtil.getDatanodeInfo("1.2.3.4", "bogus", 1234),
            dn2, replica2);
    syncList.add(record1);
    syncList.add(record2);

    when(dn1.updateReplicaUnderRecovery((ExtendedBlock) anyObject(), anyLong(),
        anyLong())).thenReturn("storage1");
    when(dn2.updateReplicaUnderRecovery((ExtendedBlock) anyObject(), anyLong(),
        anyLong())).thenReturn("storage2");
    dn.syncBlock(rBlock, syncList);
  }

  /**
   * BlockRecovery_02.8.
   * Two replicas are in Finalized state
   *
   * @throws IOException
   *     in case of an error
   */
  @Test
  public void testFinalizedReplicas() throws IOException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Running " + GenericTestUtils.getMethodName());
    }
    ReplicaRecoveryInfo replica1 =
        new ReplicaRecoveryInfo(BLOCK_ID, REPLICA_LEN1, GEN_STAMP - 1,
            ReplicaState.FINALIZED);
    ReplicaRecoveryInfo replica2 =
        new ReplicaRecoveryInfo(BLOCK_ID, REPLICA_LEN1, GEN_STAMP - 2,
            ReplicaState.FINALIZED);

    InterDatanodeProtocol dn1 = mock(InterDatanodeProtocol.class);
    InterDatanodeProtocol dn2 = mock(InterDatanodeProtocol.class);

    testSyncReplicas(replica1, replica2, dn1, dn2, REPLICA_LEN1);
    verify(dn1).updateReplicaUnderRecovery(block, RECOVERY_ID, REPLICA_LEN1);
    verify(dn2).updateReplicaUnderRecovery(block, RECOVERY_ID, REPLICA_LEN1);

    // two finalized replicas have different length
    replica1 = new ReplicaRecoveryInfo(BLOCK_ID, REPLICA_LEN1, GEN_STAMP - 1,
        ReplicaState.FINALIZED);
    replica2 = new ReplicaRecoveryInfo(BLOCK_ID, REPLICA_LEN2, GEN_STAMP - 2,
        ReplicaState.FINALIZED);

    try {
      testSyncReplicas(replica1, replica2, dn1, dn2, REPLICA_LEN1);
      Assert.fail("Two finalized replicas should not have different lengthes!");
    } catch (IOException e) {
      e.printStackTrace();
      Assert.assertTrue(e.getMessage()
          .startsWith("Inconsistent size of finalized replicas. "));
    }
  }

  /**
   * BlockRecovery_02.9.
   * One replica is Finalized and another is RBW.
   *
   * @throws IOException
   *     in case of an error
   */
  @Test
  public void testFinalizedRbwReplicas() throws IOException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Running " + GenericTestUtils.getMethodName());
    }

    // rbw and finalized replicas have the same length
    ReplicaRecoveryInfo replica1 =
        new ReplicaRecoveryInfo(BLOCK_ID, REPLICA_LEN1, GEN_STAMP - 1,
            ReplicaState.FINALIZED);
    ReplicaRecoveryInfo replica2 =
        new ReplicaRecoveryInfo(BLOCK_ID, REPLICA_LEN1, GEN_STAMP - 2,
            ReplicaState.RBW);

    InterDatanodeProtocol dn1 = mock(InterDatanodeProtocol.class);
    InterDatanodeProtocol dn2 = mock(InterDatanodeProtocol.class);

    testSyncReplicas(replica1, replica2, dn1, dn2, REPLICA_LEN1);
    verify(dn1).updateReplicaUnderRecovery(block, RECOVERY_ID, REPLICA_LEN1);
    verify(dn2).updateReplicaUnderRecovery(block, RECOVERY_ID, REPLICA_LEN1);

    // rbw replica has a different length from the finalized one
    replica1 = new ReplicaRecoveryInfo(BLOCK_ID, REPLICA_LEN1, GEN_STAMP - 1,
        ReplicaState.FINALIZED);
    replica2 = new ReplicaRecoveryInfo(BLOCK_ID, REPLICA_LEN2, GEN_STAMP - 2,
        ReplicaState.RBW);

    dn1 = mock(InterDatanodeProtocol.class);
    dn2 = mock(InterDatanodeProtocol.class);

    testSyncReplicas(replica1, replica2, dn1, dn2, REPLICA_LEN1);
    verify(dn1).updateReplicaUnderRecovery(block, RECOVERY_ID, REPLICA_LEN1);
    verify(dn2, never())
        .updateReplicaUnderRecovery(block, RECOVERY_ID, REPLICA_LEN1);
  }

  /**
   * BlockRecovery_02.10.
   * One replica is Finalized and another is RWR.
   *
   * @throws IOException
   *     in case of an error
   */
  @Test
  public void testFinalizedRwrReplicas() throws IOException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Running " + GenericTestUtils.getMethodName());
    }

    // rbw and finalized replicas have the same length
    ReplicaRecoveryInfo replica1 =
        new ReplicaRecoveryInfo(BLOCK_ID, REPLICA_LEN1, GEN_STAMP - 1,
            ReplicaState.FINALIZED);
    ReplicaRecoveryInfo replica2 =
        new ReplicaRecoveryInfo(BLOCK_ID, REPLICA_LEN1, GEN_STAMP - 2,
            ReplicaState.RWR);

    InterDatanodeProtocol dn1 = mock(InterDatanodeProtocol.class);
    InterDatanodeProtocol dn2 = mock(InterDatanodeProtocol.class);

    testSyncReplicas(replica1, replica2, dn1, dn2, REPLICA_LEN1);
    verify(dn1).updateReplicaUnderRecovery(block, RECOVERY_ID, REPLICA_LEN1);
    verify(dn2, never())
        .updateReplicaUnderRecovery(block, RECOVERY_ID, REPLICA_LEN1);

    // rbw replica has a different length from the finalized one
    replica1 = new ReplicaRecoveryInfo(BLOCK_ID, REPLICA_LEN1, GEN_STAMP - 1,
        ReplicaState.FINALIZED);
    replica2 = new ReplicaRecoveryInfo(BLOCK_ID, REPLICA_LEN2, GEN_STAMP - 2,
        ReplicaState.RBW);

    dn1 = mock(InterDatanodeProtocol.class);
    dn2 = mock(InterDatanodeProtocol.class);

    testSyncReplicas(replica1, replica2, dn1, dn2, REPLICA_LEN1);
    verify(dn1).updateReplicaUnderRecovery(block, RECOVERY_ID, REPLICA_LEN1);
    verify(dn2, never())
        .updateReplicaUnderRecovery(block, RECOVERY_ID, REPLICA_LEN1);
  }

  /**
   * BlockRecovery_02.11.
   * Two replicas are RBW.
   *
   * @throws IOException
   *     in case of an error
   */
  @Test
  public void testRBWReplicas() throws IOException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Running " + GenericTestUtils.getMethodName());
    }
    ReplicaRecoveryInfo replica1 =
        new ReplicaRecoveryInfo(BLOCK_ID, REPLICA_LEN1, GEN_STAMP - 1,
            ReplicaState.RBW);
    ReplicaRecoveryInfo replica2 =
        new ReplicaRecoveryInfo(BLOCK_ID, REPLICA_LEN2, GEN_STAMP - 2,
            ReplicaState.RBW);

    InterDatanodeProtocol dn1 = mock(InterDatanodeProtocol.class);
    InterDatanodeProtocol dn2 = mock(InterDatanodeProtocol.class);

    long minLen = Math.min(REPLICA_LEN1, REPLICA_LEN2);
    testSyncReplicas(replica1, replica2, dn1, dn2, minLen);
    verify(dn1).updateReplicaUnderRecovery(block, RECOVERY_ID, minLen);
    verify(dn2).updateReplicaUnderRecovery(block, RECOVERY_ID, minLen);
  }

  /**
   * BlockRecovery_02.12.
   * One replica is RBW and another is RWR.
   *
   * @throws IOException
   *     in case of an error
   */
  @Test
  public void testRBW_RWRReplicas() throws IOException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Running " + GenericTestUtils.getMethodName());
    }
    ReplicaRecoveryInfo replica1 =
        new ReplicaRecoveryInfo(BLOCK_ID, REPLICA_LEN1, GEN_STAMP - 1,
            ReplicaState.RBW);
    ReplicaRecoveryInfo replica2 =
        new ReplicaRecoveryInfo(BLOCK_ID, REPLICA_LEN1, GEN_STAMP - 2,
            ReplicaState.RWR);

    InterDatanodeProtocol dn1 = mock(InterDatanodeProtocol.class);
    InterDatanodeProtocol dn2 = mock(InterDatanodeProtocol.class);

    testSyncReplicas(replica1, replica2, dn1, dn2, REPLICA_LEN1);
    verify(dn1).updateReplicaUnderRecovery(block, RECOVERY_ID, REPLICA_LEN1);
    verify(dn2, never())
        .updateReplicaUnderRecovery(block, RECOVERY_ID, REPLICA_LEN1);
  }

  /**
   * BlockRecovery_02.13.
   * Two replicas are RWR.
   *
   * @throws IOException
   *     in case of an error
   */
  @Test
  public void testRWRReplicas() throws IOException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Running " + GenericTestUtils.getMethodName());
    }
    ReplicaRecoveryInfo replica1 =
        new ReplicaRecoveryInfo(BLOCK_ID, REPLICA_LEN1, GEN_STAMP - 1,
            ReplicaState.RWR);
    ReplicaRecoveryInfo replica2 =
        new ReplicaRecoveryInfo(BLOCK_ID, REPLICA_LEN2, GEN_STAMP - 2,
            ReplicaState.RWR);

    InterDatanodeProtocol dn1 = mock(InterDatanodeProtocol.class);
    InterDatanodeProtocol dn2 = mock(InterDatanodeProtocol.class);

    long minLen = Math.min(REPLICA_LEN1, REPLICA_LEN2);
    testSyncReplicas(replica1, replica2, dn1, dn2, minLen);

    verify(dn1).updateReplicaUnderRecovery(block, RECOVERY_ID, minLen);
    verify(dn2).updateReplicaUnderRecovery(block, RECOVERY_ID, minLen);
  }

  private Collection<RecoveringBlock> initRecoveringBlocks()
      throws IOException {
    Collection<RecoveringBlock> blocks = new ArrayList<RecoveringBlock>(1);
    DatanodeInfo mockOtherDN = DFSTestUtil.getLocalDatanodeInfo();
    DatanodeInfo[] locs = new DatanodeInfo[]{
        new DatanodeInfo(dn.getDNRegistrationForBP(block.getBlockPoolId())),
        mockOtherDN};
    RecoveringBlock rBlock = new RecoveringBlock(block, locs, RECOVERY_ID);
    blocks.add(rBlock);
    return blocks;
  }

  /**
   * BlockRecoveryFI_05. One DN throws RecoveryInProgressException.
   *
   * @throws IOException
   *     in case of an error
   */
  @Test
  public void testRecoveryInProgressException()
      throws IOException, InterruptedException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Running " + GenericTestUtils.getMethodName());
    }
    try {
      DataNode spyDN = spy(dn);
      doThrow(
          new RecoveryInProgressException("Replica recovery is in progress")).
          when(spyDN).initReplicaRecovery(any(RecoveringBlock.class));
      Daemon d = spyDN.recoverBlocks("fake NN", initRecoveringBlocks());
      d.join();
      verify(spyDN, never())
          .syncBlock(any(RecoveringBlock.class), anyListOf(BlockRecord.class));
    } catch (Exception e) {
      e.printStackTrace();
    }

  }

  /**
   * BlockRecoveryFI_06. all datanodes throws an exception.
   *
   * @throws IOException
   *     in case of an error
   */
  @Test
  public void testErrorReplicas() throws IOException, InterruptedException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Running " + GenericTestUtils.getMethodName());
    }
    DataNode spyDN = spy(dn);
    doThrow(new IOException()).
        when(spyDN).initReplicaRecovery(any(RecoveringBlock.class));
    Daemon d = spyDN.recoverBlocks("fake NN", initRecoveringBlocks());
    d.join();
    verify(spyDN, never())
        .syncBlock(any(RecoveringBlock.class), anyListOf(BlockRecord.class));
  }

  /**
   * BlockRecoveryFI_07. max replica length from all DNs is zero.
   *
   * @throws IOException
   *     in case of an error
   */
  @Test
  public void testZeroLenReplicas() throws IOException, InterruptedException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Running " + GenericTestUtils.getMethodName());
    }
    DataNode spyDN = spy(dn);
    doReturn(new ReplicaRecoveryInfo(block.getBlockId(), 0,
        block.getGenerationStamp(), ReplicaState.FINALIZED)).when(spyDN).
        initReplicaRecovery(any(RecoveringBlock.class));
    Daemon d = spyDN.recoverBlocks("fake NN", initRecoveringBlocks());
    d.join();
    DatanodeProtocol dnP = dn.getActiveNamenodeForBP(POOL_ID);
    verify(dnP).commitBlockSynchronization(block, RECOVERY_ID, 0, true, true,
        DatanodeID.EMPTY_ARRAY, null);
  }

  private List<BlockRecord> initBlockRecords(DataNode spyDN)
      throws IOException {
    List<BlockRecord> blocks = new ArrayList<BlockRecord>(1);
    DatanodeRegistration dnR =
        dn.getDNRegistrationForBP(block.getBlockPoolId());
    BlockRecord blockRecord = new BlockRecord(new DatanodeID(dnR), spyDN,
        new ReplicaRecoveryInfo(block.getBlockId(), block.getNumBytes(),
            block.getGenerationStamp(), ReplicaState.FINALIZED));
    blocks.add(blockRecord);
    return blocks;
  }

  private final static RecoveringBlock rBlock =
      new RecoveringBlock(block, null, RECOVERY_ID);

  /**
   * BlockRecoveryFI_09. some/all DNs failed to update replicas.
   *
   * @throws IOException
   *     in case of an error
   */
  @Test
  public void testFailedReplicaUpdate() throws IOException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Running " + GenericTestUtils.getMethodName());
    }
    DataNode spyDN = spy(dn);
    doThrow(new IOException()).when(spyDN)
        .updateReplicaUnderRecovery(block, RECOVERY_ID, block.getNumBytes());
    try {
      spyDN.syncBlock(rBlock, initBlockRecords(spyDN));
      fail("Sync should fail");
    } catch (IOException e) {
      e.getMessage().startsWith("Cannot recover ");
    }
  }

  /**
   * BlockRecoveryFI_10. DN has no ReplicaUnderRecovery.
   *
   * @throws IOException
   *     in case of an error
   */
  @Test
  public void testNoReplicaUnderRecovery() throws IOException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Running " + GenericTestUtils.getMethodName());
    }
    dn.data.createRbw(block);
    try {
      dn.syncBlock(rBlock, initBlockRecords(dn));
      fail("Sync should fail");
    } catch (IOException e) {
      e.getMessage().startsWith("Cannot recover ");
    }
    DatanodeProtocol namenode = dn.getActiveNamenodeForBP(POOL_ID);
    verify(namenode, never())
        .commitBlockSynchronization(any(ExtendedBlock.class), anyLong(),
            anyLong(), anyBoolean(), anyBoolean(), any(DatanodeID[].class),
            any(String[].class));
  }

  /**
   * BlockRecoveryFI_11. a replica's recovery id does not match new GS.
   *
   * @throws IOException
   *     in case of an error
   */
  @Test
  public void testNotMatchedReplicaID() throws IOException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Running " + GenericTestUtils.getMethodName());
    }
    ReplicaInPipelineInterface replicaInfo = dn.data.createRbw(block);
    ReplicaOutputStreams streams = null;
    try {
      streams = replicaInfo.createStreams(true,
          DataChecksum.newDataChecksum(DataChecksum.Type.CRC32, 512));
      streams.getChecksumOut().write('a');
      dn.data.initReplicaRecovery(
          new RecoveringBlock(block, null, RECOVERY_ID + 1));
      try {
        dn.syncBlock(rBlock, initBlockRecords(dn));
        fail("Sync should fail");
      } catch (IOException e) {
        e.getMessage().startsWith("Cannot recover ");
      }
      DatanodeProtocol namenode = dn.getActiveNamenodeForBP(POOL_ID);
      verify(namenode, never())
          .commitBlockSynchronization(any(ExtendedBlock.class), anyLong(),
              anyLong(), anyBoolean(), anyBoolean(), any(DatanodeID[].class),
              any(String[].class));
    } finally {
      streams.close();
    }
  }

  /**
   * Test to verify the race between finalizeBlock and Lease recovery
   *
   * @throws Exception
   */
  @Test(timeout = 20000)
  public void testRaceBetweenReplicaRecoveryAndFinalizeBlock()
      throws Exception {
    tearDown();// Stop the Mocked DN started in startup()

    Configuration conf = new HdfsConfiguration();
    MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf)
        .nnTopology(MiniDFSNNTopology.simpleSingleNN(8020, 50070))
        .numDataNodes(1).build();
    try {
      cluster.waitClusterUp();
      DistributedFileSystem fs = cluster.getFileSystem();
      Path path = new Path("/test");
      FSDataOutputStream out = fs.create(path);
      out.writeBytes("data");
      out.hsync();

      List<LocatedBlock> blocks = DFSTestUtil.getAllBlocks(fs.open(path));
      final LocatedBlock block = blocks.get(0);
      final DataNode dataNode = cluster.getDataNodes().get(0);

      final AtomicBoolean recoveryInitResult = new AtomicBoolean(true);
      Thread recoveryThread = new Thread() {
        @Override
        public void run() {
          try {
            DatanodeInfo[] locations = block.getLocations();
            final RecoveringBlock recoveringBlock =
                new RecoveringBlock(block.getBlock(), locations,
                    block.getBlock().getGenerationStamp() + 1);
            synchronized (dataNode.data) {
              Thread.sleep(2000);
              dataNode.initReplicaRecovery(recoveringBlock);
            }
          } catch (Exception e) {
            recoveryInitResult.set(false);
          }
        }
      };
      recoveryThread.start();
      try {
        out.close();
      } catch (IOException e) {
        Assert.assertTrue("Writing should fail",
            e.getMessage().contains("are bad. Aborting..."));
      } finally {
        recoveryThread.join();
      }
      Assert.assertTrue("Recovery should be initiated successfully",
          recoveryInitResult.get());

      dataNode.updateReplicaUnderRecovery(block.getBlock(),
          block.getBlock().getGenerationStamp() + 1, block.getBlockSize());
    } finally {
      if (null != cluster) {
        cluster.shutdown();
        cluster = null;
      }
    }
  }
}


text:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;

namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Recommendations
{
    [Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
    public class ElseKeywordRecommenderTests : KeywordRecommenderTests
    {
        [Fact]
        public async Task TestNotAtRoot_Interactive()
        {
            await VerifyAbsenceAsync(SourceCodeKind.Script,
@"$$");
        }

        [Fact]
        public async Task TestNotAfterClass_Interactive()
        {
            await VerifyAbsenceAsync(SourceCodeKind.Script,
@"class C { }
$$");
        }

        [Fact]
        public async Task TestNotAfterGlobalStatement_Interactive()
        {
            await VerifyAbsenceAsync(SourceCodeKind.Script,
@"System.Console.WriteLine();
$$");
        }

        [Fact]
        public async Task TestNotAfterGlobalVariableDeclaration_Interactive()
        {
            await VerifyAbsenceAsync(SourceCodeKind.Script,
@"int i = 0;
$$");
        }

        [Fact]
        public async Task TestNotInUsingAlias()
        {
            await VerifyAbsenceAsync(
@"using Goo = $$");
        }

        [Fact]
        public async Task TestNotInGlobalUsingAlias()
        {
            await VerifyAbsenceAsync(
@"global using Goo = $$");
        }

        [Fact]
        public async Task TestNotInPreprocessor1()
        {
            await VerifyAbsenceAsync(
@"class C {
#if $$");
        }

        [Fact]
        public async Task TestInPreprocessorFollowedBySkippedTokens()
        {
            await VerifyKeywordAsync(
@"#if GOO
#$$
dasd
");
        }

        [Fact]
        public async Task TestNotInEmptyStatement()
        {
            await VerifyAbsenceAsync(AddInsideMethod(
@"$$"));
        }

        [Fact]
        public async Task TestAfterHash()
        {
            await VerifyKeywordAsync(
@"#$$");
        }

        [Fact]
        public async Task TestAfterHashAndSpace()
        {
            await VerifyKeywordAsync(
@"# $$");
        }

        [Fact]
        public async Task TestNotAfterIf()
        {
            await VerifyAbsenceAsync(AddInsideMethod(
@"if (true)
$$"));
        }

        [Theory]
        [InlineData("Console.WriteLine();")]
        [InlineData("{ }")]
        [InlineData("while (true) { }")]
        public async Task TestAfterIfStatement(string statement)
        {
            await VerifyKeywordAsync(AddInsideMethod(
$@"if (true)
    {statement}
$$"));
        }

        [Theory]
        [InlineData("Console.WriteLine();")]
        [InlineData("{ }")]
        [InlineData("while (true) { }")]
        public async Task TestAfterIfStatement_BeforeElse(string statement)
        {
            await VerifyKeywordAsync(AddInsideMethod(
$@"if (true)
    {statement}
$$
else"));
        }

        [Theory]
        [InlineData("Console.WriteLine();")]
        [InlineData("{ }")]
        [InlineData("while (true) { }")]
        public async Task TestAfterIfNestedIfStatement(string statement)
        {
            await VerifyKeywordAsync(AddInsideMethod(
$@"if (true)
    if (true)
        {statement}
    $$"));
        }

        [Theory]
        [InlineData("Console.WriteLine();")]
        [InlineData("{ }")]
        [InlineData("while (true) { }")]
        public async Task TestAfterIfNestedIfStatement_BeforeElse(string statement)
        {
            await VerifyKeywordAsync(AddInsideMethod(
$@"if (true)
    if (true)
        {statement}
    $$
    else"));
        }

        [Theory, WorkItem(25336, "https://github.com/dotnet/roslyn/issues/25336")]
        [InlineData("Console.WriteLine();")]
        [InlineData("{ }")]
        [InlineData("while (true) { }")]
        public async Task TestAfterIfNestedIfElseStatement(string statement)
        {
            await VerifyKeywordAsync(AddInsideMethod(
$@"if (true)
    if (true)
        Console.WriteLine();
    else
        {statement}
$$"));
        }

        [Theory, WorkItem(25336, "https://github.com/dotnet/roslyn/issues/25336")]
        [InlineData("Console.WriteLine();")]
        [InlineData("{ }")]
        [InlineData("while (true) { }")]
        public async Task TestAfterIfNestedIfElseStatement_BeforeElse(string statement)
        {
            await VerifyKeywordAsync(AddInsideMethod(
$@"if (true)
    if (true)
        Console.WriteLine();
    else
        {statement}
$$
else"));
        }

        [Theory]
        [InlineData("Console.WriteLine();")]
        [InlineData("{ }")]
        [InlineData("while (true) { }")]
        public async Task TestNotAfterIfNestedIfElseElseStatement(string statement)
        {
            await VerifyAbsenceAsync(AddInsideMethod(
$@"if (true)
    if (true)
        Console.WriteLine();
    else
        Console.WriteLine();
else
    {statement}
$$"));
        }

        [Theory]
        [InlineData("Console.WriteLine();")]
        [InlineData("{ }")]
        [InlineData("while (true) { }")]
        public async Task TestNotAfterIfStatementElse(string statement)
        {
            await VerifyAbsenceAsync(AddInsideMethod(
$@"if (true)
    {statement}
else
    $$"));
        }

        [Theory]
        [InlineData("Console.WriteLine();")]
        [InlineData("{ }")]
        [InlineData("while (true) { }")]
        public async Task TestNotAfterIfElseStatement(string statement)
        {
            await VerifyAbsenceAsync(AddInsideMethod(
$@"if (true)
    Console.WriteLine();
else
    {statement}
$$"));
        }

        [Theory]
        [InlineData("Console.WriteLine();")]
        [InlineData("{ }")]
        [InlineData("while (true) { }")]
        public async Task TestAfterIfElseNestedIfStatement(string statement)
        {
            await VerifyKeywordAsync(AddInsideMethod(
$@"if (true)
    Console.WriteLine();
else
    if (true)
        {statement}
    $$"));
        }

        [Theory]
        [InlineData("Console.WriteLine();")]
        [InlineData("{ }")]
        [InlineData("while (true) { }")]
        public async Task TestAfterIfElseNestedIfStatement_BeforeElse(string statement)
        {
            await VerifyKeywordAsync(AddInsideMethod(
$@"if (true)
    Console.WriteLine();
else
    if (true)
        {statement}
    $$
    else"));
        }

        [Theory]
        [InlineData("Console.WriteLine();")]
        [InlineData("{ }")]
        [InlineData("while (true) { }")]
        public async Task TestNotAfterIfElseNestedIfElseStatement(string statement)
        {
            await VerifyAbsenceAsync(AddInsideMethod(
$@"if (true)
    Console.WriteLine();
else
    if (true)
        Console.WriteLine();
    else
        {statement}
$$"));
        }

        [Theory]
        [InlineData("Console.WriteLine();")]
        [InlineData("{ }")]
        [InlineData("while (true) { }")]
        public async Task TestAfterWhileIfWhileNestedIfElseStatement(string statement)
        {
            await VerifyKeywordAsync(AddInsideMethod(
$@"while (true)
    if (true)
        while (true)
            if (true)
                Console.WriteLine();
            else
                {statement}
    $$"));
        }

        [Theory]
        [InlineData("Console.WriteLine();")]
        [InlineData("{ }")]
        [InlineData("while (true) { }")]
        public async Task TestAfterWhileIfWhileNestedIfElseStatement_BeforeElse(string statement)
        {
            await VerifyKeywordAsync(AddInsideMethod(
$@"while (true)
    if (true)
        while (true)
            if (true)
                Console.WriteLine();
            else
                {statement}
    $$
    else"));
        }

        [Theory]
        [InlineData("Console.WriteLine();")]
        [InlineData("{ }")]
        [InlineData("while (true) { }")]
        public async Task TestNotAfterWhileIfWhileNestedIfElseElseStatement(string statement)
        {
            await VerifyAbsenceAsync(AddInsideMethod(
$@"while (true)
    if (true)
        while (true)
            if (true)
                Console.WriteLine();
            else
                Console.WriteLine();
    else
        {statement}
$$"));
        }

        [Theory]
        [InlineData("Console")]
        [InlineData("Console.")]
        [InlineData("Console.WriteLine(")]
        [InlineData("Console.WriteLine()")]
        [InlineData("{")]
        [InlineData("{ Console.WriteLine();")]
        [InlineData("while")]
        [InlineData("while (true)")]
        [InlineData("while (true) {")]
        [InlineData("while (true) { { }")]
        [InlineData("for (int i = 0;")]
        public async Task TestNotAfterIfIncompleteStatement(string statement)
        {
            await VerifyAbsenceAsync(AddInsideMethod(
$@"if (true)
    {statement}
$$"));
        }

        [Theory]
        [InlineData("Console")]
        [InlineData("Console.")]
        [InlineData("Console.WriteLine(")]
        [InlineData("Console.WriteLine()")]
        [InlineData("{")]
        [InlineData("{ Console.WriteLine();")]
        [InlineData("while")]
        [InlineData("while (true)")]
        [InlineData("while (true) {")]
        [InlineData("while (true) { { }")]
        [InlineData("for (int i = 0;")]
        public async Task TestNotAfterIfNestedIfIncompleteStatement(string statement)
        {
            await VerifyAbsenceAsync(AddInsideMethod(
$@"if (true)
    if (true)
        {statement}
    $$"));
        }

        [Theory]
        [InlineData("Console")]
        [InlineData("Console.")]
        [InlineData("Console.WriteLine(")]
        [InlineData("Console.WriteLine()")]
        [InlineData("{")]
        [InlineData("{ Console.WriteLine();")]
        [InlineData("while")]
        [InlineData("while (true)")]
        [InlineData("while (true) {")]
        [InlineData("while (true) { { }")]
        [InlineData("for (int i = 0;")]
        public async Task TestNotAfterIfNestedIfElseIncompleteStatement(string statement)
        {
            await VerifyAbsenceAsync(AddInsideMethod(
$@"if (true)
    if (true)
        Console.WriteLine();
    else
        {statement}
$$"));
        }

        [Theory]
        [InlineData("Console.WriteLine();")]
        [InlineData("{ }")]
        [InlineData("while (true) { }")]
        public async Task TestAfterIfNestedIfIncompleteStatementElseStatement(string statement)
        {
            await VerifyKeywordAsync(AddInsideMethod(
$@"if (true)
    if (true)
        Console // Incomplete, but that's fine. This is not the if statement we care about.
    else
        {statement}
$$"));
        }

        [Theory]
        [InlineData("Console.WriteLine();")]
        [InlineData("{ }")]
        [InlineData("while (true) { }")]
        public async Task TestAfterIfNestedIfIncompleteStatementElseStatement_BeforeElse(string statement)
        {
            await VerifyKeywordAsync(AddInsideMethod(
$@"if (true)
    if (true)
        Console // Incomplete, but that's fine. This is not the if statement we care about.
    else
        {statement}
$$
else"));
        }

        [Fact]
        public async Task TestNotInsideStatement()
        {
            await VerifyAbsenceAsync(AddInsideMethod(
@"if (true)
    Console.WriteLine()$$; // Complete statement, but we're not at the end of it.
"));
        }

        [Fact]
        public async Task TestNotAfterSkippedToken()
        {
            await VerifyAbsenceAsync(AddInsideMethod(
@"if (true)
    Console.WriteLine();,
$$"));
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
var util = require('util');
var Blueprint = require('./bpBase');
var consts = require('../../../consts/consts');
var utils = require('../../../util/utils');

var BpLighthouse = function(id, card) {
  Blueprint.call(this, id, card);
  this.triggerTiming = consts.ROOM.EFFECT_TRIGGER_TIMING.LIGHTHOUSE;
};

util.inherits(BpLighthouse, Blueprint);

BpLighthouse.prototype.handleEffect = function() {
  if(!this.playerObj) {
    return;
  }

  var bps = this.playerObj.blueprints;
  if(bps.length < consts.ROOM.MAX_BLUEPRINT_NUM_IN_HAND) {
    if(!!this.roomObj) {
      var bp = this.roomObj.getNextBlueprint();
      if(bp) {
        this.playerObj.blueprints.push(bp);
      }

      this.updatePlayerBlueprint();
      this.showPurpleFlag();
    }
  }
};

/**
 * Expose 'BpLighthouse' constructor.
 */
module.exports = BpLighthouse;


text:
<?xml version="1.0" encoding="UTF-8" ?>
        <XML>
            <Content>UPDATE</Content>
            <Clip>
                <ClipName>DOCUCUL0010</ClipName>
                <TipoContenido>DOCUMENTALES</TipoContenido>
                <Contenido><![CDATA[ CANTORA UN VIAJE INTIMO 04OCT14 ]]></Contenido>
                <OriginalTitle></OriginalTitle>
                <Description> </Description>
                <Notes>a</Notes>
                <DurPrev></DurPrev>
                <Chapter></Chapter>
                <EndDate></EndDate>
                <EPG></EPG>
                <EPG_Content> </EPG_Content>
                <Segments>

                <Segment>
                    <SegTitle>1-2 CULTURALES - CANTORA UN VIAJE INTIMO 04OCT14 </SegTitle>
                    <MediaID>DOCUCUL001001</MediaID>
                    <Duration>00:29:00.00</Duration>
                    <SegNumber>1</SegNumber>
                    <ClipGroup>PROGRAMA</ClipGroup>
                    <Description> </Description>
                </Segment>

                <Segment>
                    <SegTitle>2-2 CULTURALES - CANTORA UN VIAJE INTIMO 04OCT14 </SegTitle>
                    <MediaID>DOCUCUL001002</MediaID>
                    <Duration>00:29:00.00</Duration>
                    <SegNumber>2</SegNumber>
                    <ClipGroup>PROGRAMA</ClipGroup>
                    <Description> </Description>
                </Segment>
            </Segments></Clip></XML>


text:
package amt

import (
	"fmt"
	amtgen "github.com/jesand/crowds/amt/gen/mechanicalturk.amazonaws.com/AWSMechanicalTurk/2014-08-15/AWSMechanicalTurkRequester.xsd_go"
	xsdt "github.com/metaleap/go-xsd/types"
	"sort"
	"strings"
)

// ApproveAssignment approves the results of a completed assignment.
func (client amtClient) ApproveAssignment(assignmentId,
	requesterFeedback string) (amtgen.TxsdApproveAssignmentResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdApproveAssignment
		args     amtgen.TApproveAssignmentRequest
		response amtgen.TxsdApproveAssignmentResponse
	)
	args.AssignmentId = xsdt.String(assignmentId)
	args.RequesterFeedback = xsdt.String(requesterFeedback)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("ApproveAssignment", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// ApproveRejectedAssignment approves an assignment that was previously
// rejected.
func (client amtClient) ApproveRejectedAssignment(assignmentId,
	requesterFeedback string) (amtgen.TxsdApproveRejectedAssignmentResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdApproveRejectedAssignment
		args     amtgen.TApproveRejectedAssignmentRequest
		response amtgen.TxsdApproveRejectedAssignmentResponse
	)
	args.AssignmentId = xsdt.String(assignmentId)
	args.RequesterFeedback = xsdt.String(requesterFeedback)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("ApproveRejectedAssignment", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// AssignQualification gives a Worker a Qualification.
func (client amtClient) AssignQualification(qualificationTypeId,
	workerId string, integerValue int, sendNotification bool) (
	amtgen.TxsdAssignQualificationResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdAssignQualification
		args     amtgen.TAssignQualificationRequest
		response amtgen.TxsdAssignQualificationResponse
	)
	args.QualificationTypeId = xsdt.String(qualificationTypeId)
	args.WorkerId = xsdt.String(workerId)
	args.IntegerValue = xsdt.Int(integerValue)
	args.SendNotification = xsdt.Boolean(sendNotification)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("AssignQualification", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// BlockWorker allows you to prevent a Worker from working on your HITs.
func (client amtClient) BlockWorker(workerId, reason string) (
	amtgen.TxsdBlockWorkerResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdBlockWorker
		args     amtgen.TBlockWorkerRequest
		response amtgen.TxsdBlockWorkerResponse
	)
	args.WorkerId = xsdt.String(workerId)
	args.Reason = xsdt.String(reason)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("BlockWorker", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// ChangeHITTypeOfHIT allows you to change the HITType properties of a HIT.
func (client amtClient) ChangeHITTypeOfHIT(hitId, hitTypeId string) (
	amtgen.TxsdChangeHITTypeOfHITResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdChangeHITTypeOfHIT
		args     amtgen.TChangeHITTypeOfHITRequest
		response amtgen.TxsdChangeHITTypeOfHITResponse
	)
	args.HITId = xsdt.String(hitId)
	args.HITTypeId = xsdt.String(hitTypeId)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("ChangeHITTypeOfHIT", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// CreateHIT creates a new Human Intelligence Task (HIT) without a HITTypeId.
func (client amtClient) CreateHIT(title, description, question string,
	hitLayoutId string, hitLayoutParameters map[string]string,
	reward float32, assignmentDurationInSeconds,
	lifetimeInSeconds, maxAssignments, autoApprovalDelayInSeconds int,
	keywords []string,
	qualificationRequirements []*amtgen.TQualificationRequirement,
	assignmentReviewPolicy, hitReviewPolicy *amtgen.TReviewPolicy,
	requesterAnnotation, uniqueRequestToken string) (
	amtgen.TxsdCreateHITResponse, error) {

	// Prepare the request
	var (
		args amtgen.TCreateHITRequest
	)
	args.Title = xsdt.String(title)
	args.Description = xsdt.String(description)
	args.Question = xsdt.String(question)
	args.HITLayoutId = xsdt.String(hitLayoutId)
	var hitLayoutParameterOrder []string
	for name, _ := range hitLayoutParameters {
		hitLayoutParameterOrder = append(hitLayoutParameterOrder, name)
	}
	sort.Strings(hitLayoutParameterOrder)
	for _, name := range hitLayoutParameterOrder {
		value := hitLayoutParameters[name]
		var param amtgen.THITLayoutParameter
		param.Name = xsdt.String(name)
		param.Value = xsdt.String(value)
		args.HITLayoutParameters = append(args.HITLayoutParameters, &param)
	}
	args.Reward = &amtgen.TPrice{}
	args.Reward.Amount = xsdt.Decimal(fmt.Sprint(reward))
	args.Reward.CurrencyCode = CURRENCY_USD
	args.AssignmentDurationInSeconds = xsdt.Long(assignmentDurationInSeconds)
	args.LifetimeInSeconds = xsdt.Long(lifetimeInSeconds)
	args.MaxAssignments = xsdt.Int(maxAssignments)
	args.AutoApprovalDelayInSeconds = xsdt.Long(autoApprovalDelayInSeconds)
	args.Keywords = xsdt.String(strings.Join(keywords, ","))
	args.QualificationRequirements = qualificationRequirements
	args.AssignmentReviewPolicy = assignmentReviewPolicy
	args.HITReviewPolicy = hitReviewPolicy
	args.RequesterAnnotation = xsdt.String(requesterAnnotation)
	args.UniqueRequestToken = xsdt.String(uniqueRequestToken)
	return client.CreateHITFromArgs(args)
}

// CreateHITFromHITTypeId creates a new Human Intelligence Task (HIT) from a
// HITTypeId.
func (client amtClient) CreateHITFromHITTypeId(hitTypeId, question string,
	hitLayoutId string, hitLayoutParameters map[string]string,
	lifetimeInSeconds, maxAssignments int,
	assignmentReviewPolicy, hitReviewPolicy *amtgen.TReviewPolicy,
	requesterAnnotation, uniqueRequestToken string) (
	amtgen.TxsdCreateHITResponse, error) {

	// Prepare the request
	var (
		args amtgen.TCreateHITRequest
	)
	args.HITTypeId = xsdt.String(hitTypeId)
	args.Question = xsdt.String(question)
	args.HITLayoutId = xsdt.String(hitLayoutId)
	var hitLayoutParameterOrder []string
	for name, _ := range hitLayoutParameters {
		hitLayoutParameterOrder = append(hitLayoutParameterOrder, name)
	}
	sort.Strings(hitLayoutParameterOrder)
	for _, name := range hitLayoutParameterOrder {
		value := hitLayoutParameters[name]
		var param amtgen.THITLayoutParameter
		param.Name = xsdt.String(name)
		param.Value = xsdt.String(value)
		args.HITLayoutParameters = append(args.HITLayoutParameters, &param)
	}
	args.LifetimeInSeconds = xsdt.Long(lifetimeInSeconds)
	args.MaxAssignments = xsdt.Int(maxAssignments)
	args.AssignmentReviewPolicy = assignmentReviewPolicy
	args.HITReviewPolicy = hitReviewPolicy
	args.RequesterAnnotation = xsdt.String(requesterAnnotation)
	args.UniqueRequestToken = xsdt.String(uniqueRequestToken)
	return client.CreateHITFromArgs(args)
}

// CreateHITFromArgs creates a new Human Intelligence Task (HIT) from the given
// argument values.
func (client amtClient) CreateHITFromArgs(args amtgen.TCreateHITRequest) (
	amtgen.TxsdCreateHITResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdCreateHIT
		response amtgen.TxsdCreateHITResponse
	)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("CreateHIT", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// CreateQualificationType creates a new Qualification type.
func (client amtClient) CreateQualificationType(name, description string,
	keywords []string, retryDelayInSeconds int,
	qualificationTypeStatus, test, answerKey string,
	testDurationInSeconds int, autoGranted bool,
	autoGrantedValue int) (amtgen.TxsdCreateQualificationTypeResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdCreateQualificationType
		args     amtgen.TCreateQualificationTypeRequest
		response amtgen.TxsdCreateQualificationTypeResponse
	)
	args.Name = xsdt.String(name)
	args.Description = xsdt.String(description)
	args.Keywords = xsdt.String(strings.Join(keywords, ","))
	args.RetryDelayInSeconds = xsdt.Long(retryDelayInSeconds)
	args.QualificationTypeStatus = amtgen.TQualificationTypeStatus(
		qualificationTypeStatus)
	args.Test = xsdt.String(test)
	args.AnswerKey = xsdt.String(answerKey)
	args.TestDurationInSeconds = xsdt.Long(testDurationInSeconds)
	args.AutoGranted = xsdt.Boolean(autoGranted)
	args.AutoGrantedValue = xsdt.Int(autoGrantedValue)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("CreateQualificationType", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// DisableHIT removes a HIT from the Amazon Mechanical Turk marketplace.
func (client amtClient) DisableHIT(hitId string) (
	amtgen.TxsdDisableHITResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdDisableHIT
		args     amtgen.TDisableHITRequest
		response amtgen.TxsdDisableHITResponse
	)
	args.HITId = xsdt.String(hitId)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("DisableHIT", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// DisposeHIT disposes of a HIT that is no longer needed.
func (client amtClient) DisposeHIT(hitId string) (
	amtgen.TxsdDisposeHITResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdDisposeHIT
		args     amtgen.TDisposeHITRequest
		response amtgen.TxsdDisposeHITResponse
	)
	args.HITId = xsdt.String(hitId)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("DisposeHIT", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// DisposeQualificationType disposes of a HIT that is no longer needed.
func (client amtClient) DisposeQualificationType(qualificationTypeId string) (
	amtgen.TxsdDisposeQualificationTypeResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdDisposeQualificationType
		args     amtgen.TDisposeQualificationTypeRequest
		response amtgen.TxsdDisposeQualificationTypeResponse
	)
	args.QualificationTypeId = xsdt.String(qualificationTypeId)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("DisposeQualificationType", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// ExtendHIT increases the maximum number of assignments, or extends the
// expiration date, of an existing HIT.
func (client amtClient) ExtendHIT(hitId string,
	maxAssignmentsIncrement, expirationIncrementInSeconds int,
	uniqueRequestToken string) (
	amtgen.TxsdExtendHITResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdExtendHIT
		args     amtgen.TExtendHITRequest
		response amtgen.TxsdExtendHITResponse
	)
	args.HITId = xsdt.String(hitId)
	args.MaxAssignmentsIncrement = xsdt.Int(maxAssignmentsIncrement)
	args.ExpirationIncrementInSeconds = xsdt.Long(expirationIncrementInSeconds)
	args.UniqueRequestToken = xsdt.String(uniqueRequestToken)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("ExtendHIT", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// ForceExpireHIT causes a HIT to expire immediately, as if the
// LifetimeInSeconds parameter of the HIT had elapsed.
func (client amtClient) ForceExpireHIT(hitId string) (
	amtgen.TxsdForceExpireHITResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdForceExpireHIT
		args     amtgen.TForceExpireHITRequest
		response amtgen.TxsdForceExpireHITResponse
	)
	args.HITId = xsdt.String(hitId)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("ForceExpireHIT", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// GetAccountBalance causes a HIT to expire immediately, as if the
// LifetimeInSeconds parameter of the HIT had elapsed.
func (client amtClient) GetAccountBalance() (
	amtgen.TxsdGetAccountBalanceResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdGetAccountBalance
		args     amtgen.TGetAccountBalanceRequest
		response amtgen.TxsdGetAccountBalanceResponse
	)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("GetAccountBalance", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// GetAssignment retrieves an assignment with an AssignmentStatus value of
// Submitted, Approved, or Rejected.
func (client amtClient) GetAssignment(assignmentId string) (
	amtgen.TxsdGetAssignmentResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdGetAssignment
		args     amtgen.TGetAssignmentRequest
		response amtgen.TxsdGetAssignmentResponse
	)
	args.AssignmentId = xsdt.String(assignmentId)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("GetAssignment", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// GetAssignmentsForHIT retrieves completed assignments for a HIT.
func (client amtClient) GetAssignmentsForHIT(hitId string,
	assignmentStatuses []string, sortProperty string, sortAscending bool,
	pageSize, pageNumber int) (
	amtgen.TxsdGetAssignmentsForHITResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdGetAssignmentsForHIT
		args     amtgen.TGetAssignmentsForHITRequest
		response amtgen.TxsdGetAssignmentsForHITResponse
	)
	args.HITId = xsdt.String(hitId)
	for _, status := range assignmentStatuses {
		args.AssignmentStatuses = append(args.AssignmentStatuses,
			amtgen.TAssignmentStatus(status))
	}
	args.SortProperty = amtgen.TGetAssignmentsForHITSortProperty(sortProperty)
	if sortAscending {
		args.SortDirection = amtgen.TSortDirection("Ascending")
	} else {
		args.SortDirection = amtgen.TSortDirection("Descending")
	}
	args.PageSize = xsdt.Int(pageSize)
	args.PageNumber = xsdt.Int(pageNumber)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("GetAssignmentsForHIT", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// GetBlockedWorkers retrieves a list of Workers who are blocked from working
// on your HITs.
func (client amtClient) GetBlockedWorkers(pageSize, pageNumber int) (
	amtgen.TxsdGetBlockedWorkersResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdGetBlockedWorkers
		args     amtgen.TGetBlockedWorkersRequest
		response amtgen.TxsdGetBlockedWorkersResponse
	)
	args.PageSize = xsdt.Int(pageSize)
	args.PageNumber = xsdt.Int(pageNumber)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("GetBlockedWorkers", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// GetBonusPayments retrieves the amounts of bonuses you have paid to Workers
// for a given HIT or assignment.
func (client amtClient) GetBonusPayments(hitId, assignmentId string,
	pageSize, pageNumber int) (
	amtgen.TxsdGetBonusPaymentsResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdGetBonusPayments
		args     amtgen.TGetBonusPaymentsRequest
		response amtgen.TxsdGetBonusPaymentsResponse
	)
	args.HITId = xsdt.String(hitId)
	args.AssignmentId = xsdt.String(assignmentId)
	args.PageSize = xsdt.Int(pageSize)
	args.PageNumber = xsdt.Int(pageNumber)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("GetBonusPayments", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// GetFileUploadURL generates and returns a temporary URL.
func (client amtClient) GetFileUploadURL(assignmentId,
	questionIdentifier string) (
	amtgen.TxsdGetFileUploadURLResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdGetFileUploadURL
		args     amtgen.TGetFileUploadURLRequest
		response amtgen.TxsdGetFileUploadURLResponse
	)
	args.AssignmentId = xsdt.String(assignmentId)
	args.QuestionIdentifier = xsdt.String(questionIdentifier)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("GetFileUploadURL", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// GetHIT retrieves the details of the specified HIT.
func (client amtClient) GetHIT(hitId string) (
	amtgen.TxsdGetHITResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdGetHIT
		args     amtgen.TGetHITRequest
		response amtgen.TxsdGetHITResponse
	)
	args.HITId = xsdt.String(hitId)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("GetHIT", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// GetHITsForQualificationType returns the HITs that use the given Qualification
// type for a Qualification requirement.
func (client amtClient) GetHITsForQualificationType(qualificationTypeId string,
	pageSize, pageNumber int) (
	amtgen.TxsdGetHITsForQualificationTypeResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdGetHITsForQualificationType
		args     amtgen.TGetHITsForQualificationTypeRequest
		response amtgen.TxsdGetHITsForQualificationTypeResponse
	)
	args.QualificationTypeId = xsdt.String(qualificationTypeId)
	args.PageSize = xsdt.Int(pageSize)
	args.PageNumber = xsdt.Int(pageNumber)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("GetHITsForQualificationType", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// GetQualificationsForQualificationType returns all of the Qualifications
// granted to Workers for a given Qualification type.
func (client amtClient) GetQualificationsForQualificationType(
	qualificationTypeId string, isGranted bool,
	pageSize, pageNumber int) (
	amtgen.TxsdGetQualificationsForQualificationTypeResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdGetQualificationsForQualificationType
		args     amtgen.TGetQualificationsForQualificationTypeRequest
		response amtgen.TxsdGetQualificationsForQualificationTypeResponse
	)
	args.QualificationTypeId = xsdt.String(qualificationTypeId)
	if isGranted {
		args.Status = amtgen.TQualificationStatus("Granted")
	} else {
		args.Status = amtgen.TQualificationStatus("Revoked")
	}
	args.PageSize = xsdt.Int(pageSize)
	args.PageNumber = xsdt.Int(pageNumber)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("GetQualificationsForQualificationType", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// GetQualificationRequests returns all of the Qualifications
// granted to Workers for a given Qualification type.
func (client amtClient) GetQualificationRequests(
	qualificationTypeId, sortProperty string, sortAscending bool,
	pageSize, pageNumber int) (
	amtgen.TxsdGetQualificationRequestsResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdGetQualificationRequests
		args     amtgen.TGetQualificationRequestsRequest
		response amtgen.TxsdGetQualificationRequestsResponse
	)
	args.QualificationTypeId = xsdt.String(qualificationTypeId)
	args.SortProperty = amtgen.TGetQualificationRequestsSortProperty(
		sortProperty)
	if sortAscending {
		args.SortDirection = amtgen.TSortDirection("Ascending")
	} else {
		args.SortDirection = amtgen.TSortDirection("Descending")
	}
	args.PageSize = xsdt.Int(pageSize)
	args.PageNumber = xsdt.Int(pageNumber)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("GetQualificationRequests", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// GetQualificationScore returns the value of a Worker's Qualification for a
// given Qualification type.
func (client amtClient) GetQualificationScore(
	qualificationTypeId, subjectId string) (
	amtgen.TxsdGetQualificationScoreResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdGetQualificationScore
		args     amtgen.TGetQualificationScoreRequest
		response amtgen.TxsdGetQualificationScoreResponse
	)
	args.QualificationTypeId = xsdt.String(qualificationTypeId)
	args.SubjectId = xsdt.String(subjectId)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("GetQualificationScore", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// GetQualificationType retrieves information about a Qualification type using
// its ID.
func (client amtClient) GetQualificationType(qualificationTypeId string) (
	amtgen.TxsdGetQualificationTypeResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdGetQualificationType
		args     amtgen.TGetQualificationTypeRequest
		response amtgen.TxsdGetQualificationTypeResponse
	)
	args.QualificationTypeId = xsdt.String(qualificationTypeId)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("GetQualificationType", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// GetRequesterStatistic retrieves statistics about you (the Requester calling
// the operation).
func (client amtClient) GetRequesterStatistic(statistic, timePeriod string,
	count int) (amtgen.TxsdGetRequesterStatisticResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdGetRequesterStatistic
		args     amtgen.TGetRequesterStatisticRequest
		response amtgen.TxsdGetRequesterStatisticResponse
	)
	args.Statistic = amtgen.TRequesterStatistic(statistic)
	args.TimePeriod = amtgen.TimePeriod(timePeriod)
	args.Count = xsdt.Int(count)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("GetRequesterStatistic", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// GetRequesterWorkerStatistic retrieves statistics about a specific Worker who
// has completed Human Intelligence Tasks (HITs) for you.
func (client amtClient) GetRequesterWorkerStatistic(statistic, workerId,
	timePeriod string, count int) (amtgen.TxsdGetRequesterWorkerStatisticResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdGetRequesterWorkerStatistic
		args     amtgen.TGetRequesterWorkerStatisticRequest
		response amtgen.TxsdGetRequesterWorkerStatisticResponse
	)
	args.Statistic = amtgen.TRequesterStatistic(statistic)
	args.WorkerId = xsdt.String(workerId)
	args.TimePeriod = amtgen.TimePeriod(timePeriod)
	args.Count = xsdt.Int(count)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("GetRequesterWorkerStatistic", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// GetReviewableHITs retrieves the HITs with Status equal to Reviewable or
// Status equal to Reviewing that belong to the Requester calling the operation.
func (client amtClient) GetReviewableHITs(hitTypeId, status,
	sortProperty string, sortAscending bool,
	pageSize, pageNumber int) (amtgen.TxsdGetReviewableHITsResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdGetReviewableHITs
		args     amtgen.TGetReviewableHITsRequest
		response amtgen.TxsdGetReviewableHITsResponse
	)
	args.HITTypeId = xsdt.String(hitTypeId)
	args.Status = amtgen.TReviewableHITStatus(status)
	args.SortProperty = amtgen.TGetReviewableHITsSortProperty(sortProperty)
	if sortAscending {
		args.SortDirection = amtgen.TSortDirection("Ascending")
	} else {
		args.SortDirection = amtgen.TSortDirection("Descending")
	}
	args.PageSize = xsdt.Int(pageSize)
	args.PageNumber = xsdt.Int(pageNumber)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("GetReviewableHITs", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// GetReviewResultsForHIT retrieves the computed results and the actions taken
// in the course of executing your Review Policies during a CreateHIT operation.
func (client amtClient) GetReviewResultsForHIT(hitId string,
	policyLevels []string,
	retrieveActions, retrieveResults bool,
	pageSize, pageNumber int) (amtgen.TxsdGetReviewResultsForHITResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdGetReviewResultsForHIT
		args     amtgen.TGetReviewResultsForHITRequest
		response amtgen.TxsdGetReviewResultsForHITResponse
	)
	args.HITId = xsdt.String(hitId)
	for _, level := range policyLevels {
		args.PolicyLevels = append(args.PolicyLevels,
			amtgen.TReviewPolicyLevel(level))
	}
	args.RetrieveActions = xsdt.Boolean(retrieveActions)
	args.RetrieveResults = xsdt.Boolean(retrieveResults)
	args.PageSize = xsdt.Int(pageSize)
	args.PageNumber = xsdt.Int(pageNumber)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("GetReviewResultsForHIT", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// GrantBonus issues a payment of money from your account to a Worker.
func (client amtClient) GrantBonus(workerId, assignmentId string,
	bonusAmount float32, reason, uniqueRequestToken string) (
	amtgen.TxsdGrantBonusResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdGrantBonus
		args     amtgen.TGrantBonusRequest
		response amtgen.TxsdGrantBonusResponse
	)
	args.WorkerId = xsdt.String(workerId)
	args.AssignmentId = xsdt.String(assignmentId)
	args.BonusAmount = &amtgen.TPrice{}
	args.BonusAmount.Amount = xsdt.Decimal(fmt.Sprint(bonusAmount))
	args.BonusAmount.CurrencyCode = CURRENCY_USD
	args.Reason = xsdt.String(reason)
	args.UniqueRequestToken = xsdt.String(uniqueRequestToken)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("GrantBonus", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// GrantQualification issues a payment of money from your account to a Worker.
func (client amtClient) GrantQualification(qualificationRequestId string,
	integerValue int) (
	amtgen.TxsdGrantQualificationResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdGrantQualification
		args     amtgen.TGrantQualificationRequest
		response amtgen.TxsdGrantQualificationResponse
	)
	args.QualificationRequestId = xsdt.String(qualificationRequestId)
	args.IntegerValue = xsdt.Int(integerValue)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("GrantQualification", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// NotifyWorkers sends an email to one or more Workers that you specify with
// the Worker ID.
func (client amtClient) NotifyWorkers(subject, messageText string,
	workerIds []string) (amtgen.TxsdNotifyWorkersResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdNotifyWorkers
		args     amtgen.TNotifyWorkersRequest
		response amtgen.TxsdNotifyWorkersResponse
	)
	args.Subject = xsdt.String(subject)
	args.MessageText = xsdt.String(messageText)
	for _, workerId := range workerIds {
		args.WorkerIds = append(args.WorkerIds, xsdt.String(workerId))
	}
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("NotifyWorkers", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// RegisterHITType creates a new HIT type.
func (client amtClient) RegisterHITType(title, description string,
	reward float32, assignmentDurationInSeconds, autoApprovalDelayInSeconds int,
	keywords []string,
	qualificationRequirements []*amtgen.TQualificationRequirement) (
	amtgen.TxsdRegisterHITTypeResponse, error) {

	// Prepare the request
	var (
		args amtgen.TRegisterHITTypeRequest
	)
	args.Title = xsdt.String(title)
	args.Description = xsdt.String(description)
	args.Reward = &amtgen.TPrice{}
	args.Reward.Amount = xsdt.Decimal(fmt.Sprint(reward))
	args.Reward.CurrencyCode = CURRENCY_USD
	args.AssignmentDurationInSeconds = xsdt.Long(assignmentDurationInSeconds)
	args.AutoApprovalDelayInSeconds = xsdt.Long(autoApprovalDelayInSeconds)
	args.Keywords = xsdt.String(strings.Join(keywords, ","))
	args.QualificationRequirements = qualificationRequirements

	return client.RegisterHITTypeFromArgs(args)
}

// RegisterHITType creates a new HIT type.
func (client amtClient) RegisterHITTypeFromArgs(args amtgen.TRegisterHITTypeRequest) (
	amtgen.TxsdRegisterHITTypeResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdRegisterHITType
		response amtgen.TxsdRegisterHITTypeResponse
	)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("RegisterHITType", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// RejectAssignment rejects the results of a completed assignment.
func (client amtClient) RejectAssignment(assignmentId,
	requesterFeedback string) (
	amtgen.TxsdRejectAssignmentResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdRejectAssignment
		args     amtgen.TRejectAssignmentRequest
		response amtgen.TxsdRejectAssignmentResponse
	)
	args.AssignmentId = xsdt.String(assignmentId)
	args.RequesterFeedback = xsdt.String(requesterFeedback)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("RejectAssignment", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// RejectQualificationRequest rejects a user's request for a Qualification.
func (client amtClient) RejectQualificationRequest(qualificationRequestId,
	reason string) (
	amtgen.TxsdRejectQualificationRequestResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdRejectQualificationRequest
		args     amtgen.TRejectQualificationRequestRequest
		response amtgen.TxsdRejectQualificationRequestResponse
	)
	args.QualificationRequestId = xsdt.String(qualificationRequestId)
	args.Reason = xsdt.String(reason)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("RejectQualificationRequest", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// RevokeQualification revokes a previously granted Qualification from a user.
func (client amtClient) RevokeQualification(subjectId, qualificationTypeId,
	reason string) (
	amtgen.TxsdRevokeQualificationResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdRevokeQualification
		args     amtgen.TRevokeQualificationRequest
		response amtgen.TxsdRevokeQualificationResponse
	)
	args.SubjectId = xsdt.String(subjectId)
	args.QualificationTypeId = xsdt.String(qualificationTypeId)
	args.Reason = xsdt.String(reason)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("RevokeQualification", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// SearchHITs returns all of a Requester's HITs, on behalf of the Requester.
func (client amtClient) SearchHITs(sortProperty string, sortAscending bool,
	pageSize, pageNumber int) (
	amtgen.TxsdSearchHITsResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdSearchHITs
		args     amtgen.TSearchHITsRequest
		response amtgen.TxsdSearchHITsResponse
	)
	args.SortProperty = amtgen.TSearchHITsSortProperty(sortProperty)
	if sortAscending {
		args.SortDirection = amtgen.TSortDirection("Ascending")
	} else {
		args.SortDirection = amtgen.TSortDirection("Descending")
	}
	args.PageSize = xsdt.Int(pageSize)
	args.PageNumber = xsdt.Int(pageNumber)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("SearchHITs", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// SearchQualificationTypes searches for Qualification types using the specified
// search query, and returns a list of Qualification types.
func (client amtClient) SearchQualificationTypes(
	query, sortProperty string, sortAscending bool,
	pageSize, pageNumber int, mustBeRequestable, mustBeOwnedByCaller bool) (
	amtgen.TxsdSearchQualificationTypesResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdSearchQualificationTypes
		args     amtgen.TSearchQualificationTypesRequest
		response amtgen.TxsdSearchQualificationTypesResponse
	)
	args.Query = xsdt.String(query)
	args.SortProperty = amtgen.TSearchQualificationTypesSortProperty(sortProperty)
	if sortAscending {
		args.SortDirection = amtgen.TSortDirection("Ascending")
	} else {
		args.SortDirection = amtgen.TSortDirection("Descending")
	}
	args.PageSize = xsdt.Int(pageSize)
	args.PageNumber = xsdt.Int(pageNumber)
	args.MustBeRequestable = xsdt.Boolean(mustBeRequestable)
	args.MustBeOwnedByCaller = xsdt.Boolean(mustBeOwnedByCaller)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("SearchQualificationTypes", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// SendTestEventNotification causes Amazon Mechanical Turk to send a
// notification message as if a HIT event occurred, according to the provided
// notification specification.
func (client amtClient) SendTestEventNotification(
	notification *amtgen.TNotificationSpecification, testEventType string) (
	amtgen.TxsdSendTestEventNotificationResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdSendTestEventNotification
		args     amtgen.TSendTestEventNotificationRequest
		response amtgen.TxsdSendTestEventNotificationResponse
	)
	args.Notification = notification
	args.TestEventType = amtgen.TEventType(testEventType)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("SendTestEventNotification", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// SetHITAsReviewing updates the status of a HIT. If the status is Reviewable,
// this operation updates the status to Reviewing, or reverts a Reviewing HIT
// back to the Reviewable status.
func (client amtClient) SetHITAsReviewing(hitID string, revert bool) (
	amtgen.TxsdSetHITAsReviewingResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdSetHITAsReviewing
		args     amtgen.TSetHITAsReviewingRequest
		response amtgen.TxsdSetHITAsReviewingResponse
	)
	args.HITId = xsdt.String(hitID)
	args.Revert = xsdt.Boolean(revert)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("SetHITAsReviewing", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// SetHITTypeNotification creates, updates, disables or re-enables notifications
// for a HIT type.
func (client amtClient) SetHITTypeNotification(hitTypeID string,
	notification *amtgen.TNotificationSpecification, active bool) (
	amtgen.TxsdSetHITTypeNotificationResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdSetHITTypeNotification
		args     amtgen.TSetHITTypeNotificationRequest
		response amtgen.TxsdSetHITTypeNotificationResponse
	)
	args.HITTypeId = xsdt.String(hitTypeID)
	args.Notification = notification
	args.Active = xsdt.Boolean(active)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("SetHITTypeNotification", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// UnblockWorker allows you to reinstate a blocked Worker to work on your HITs.
func (client amtClient) UnblockWorker(workerId, reason string) (
	amtgen.TxsdUnblockWorkerResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdUnblockWorker
		args     amtgen.TUnblockWorkerRequest
		response amtgen.TxsdUnblockWorkerResponse
	)
	args.WorkerId = xsdt.String(workerId)
	args.Reason = xsdt.String(reason)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("UnblockWorker", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// UpdateQualificationScore changes the value of a Qualification previously
// granted to a Worker.
func (client amtClient) UpdateQualificationScore(qualificationTypeId,
	subjectId string, integerValue int) (
	amtgen.TxsdUpdateQualificationScoreResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdUpdateQualificationScore
		args     amtgen.TUpdateQualificationScoreRequest
		response amtgen.TxsdUpdateQualificationScoreResponse
	)
	args.QualificationTypeId = xsdt.String(qualificationTypeId)
	args.SubjectId = xsdt.String(subjectId)
	args.IntegerValue = xsdt.Int(integerValue)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("UpdateQualificationScore", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}

// UpdateQualificationType modifies the attributes of an existing Qualification
// type.
func (client amtClient) UpdateQualificationType(qualificationTypeId string,
	retryDelayInSeconds int, qualificationTypeStatus, description, test,
	answerKey string, testDurationInSeconds int, autoGranted bool,
	autoGrantedValue int) (
	amtgen.TxsdUpdateQualificationTypeResponse, error) {

	// Prepare the request
	var (
		request  amtgen.TxsdUpdateQualificationType
		args     amtgen.TUpdateQualificationTypeRequest
		response amtgen.TxsdUpdateQualificationTypeResponse
	)
	args.QualificationTypeId = xsdt.String(qualificationTypeId)
	args.RetryDelayInSeconds = xsdt.Long(retryDelayInSeconds)
	args.QualificationTypeStatus = amtgen.TQualificationTypeStatus(
		qualificationTypeStatus)
	args.Description = xsdt.String(description)
	args.Test = xsdt.String(test)
	args.AnswerKey = xsdt.String(answerKey)
	args.TestDurationInSeconds = xsdt.Long(testDurationInSeconds)
	args.AutoGranted = xsdt.Boolean(autoGranted)
	args.AutoGrantedValue = xsdt.Int(autoGrantedValue)
	request.Requests = append(request.Requests, &args)

	// Send the request
	req, err := client.signRequest("UpdateQualificationType", &request)
	if err == nil {
		err = client.sendRequest(req, &response)
	}
	return response, err
}


text:
#include <windef.h>

/* Translation IDs. */
#define STRING_USAGE            101
#define STRING_INVALID_CMDLINE  102
#define STRING_ADAPTER_FRIENDLY 103
#define STRING_ETHERNET         104
#define STRING_UNKNOWN          105
#define STRING_CONN_DNS_SUFFIX  106
#define STRING_IP_ADDRESS       107
#define STRING_HOSTNAME         108
#define STRING_NODE_TYPE        109
#define STRING_BROADCAST        110
#define STRING_PEER_TO_PEER     111
#define STRING_MIXED            112
#define STRING_HYBRID           113
#define STRING_IP_ROUTING       114
#define STRING_DESCRIPTION      115
#define STRING_PHYS_ADDR        116
#define STRING_DHCP_ENABLED     117
#define STRING_YES              118
#define STRING_NO               119
#define STRING_DEFAULT_GATEWAY  120
#define STRING_IP6_ADDRESS      121


text:
package org.assertj.core.internal.paths;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.assertj.core.test.TestData.someInfo;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockingDetails;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.DirectoryStream;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.Spliterators;
import java.util.function.Predicate;

import org.assertj.core.api.AssertionInfo;
import org.assertj.core.internal.PathsBaseTest;
import org.assertj.core.util.Strings;
import org.junit.jupiter.api.BeforeEach;

import com.google.common.collect.Iterators;

public class MockPathsBaseTest extends PathsBaseTest {

  static final AssertionInfo INFO = someInfo();

  Path actual;
  Path other;

  @BeforeEach
  public void init() {
    actual = mock(Path.class);
    other = mock(Path.class);
  }

  static void failIfStreamIsOpen(InputStream stream) {
    try {
      assertThat(stream.read()).as("Stream should be closed").isNegative();
    } catch (IOException e) {
      assertThat(e).hasNoCause().hasMessage("Stream closed");
    }
  }

  static <T> void failIfStreamIsOpen(DirectoryStream<T> stream) {
    try {
      long openCount = mockingDetails(stream).getInvocations().stream()
                                             .filter(inv -> inv.getMethod().getName().equals("iterator"))
                                             .count();
      verify(stream, times((int) openCount)).close();
    } catch (IOException e) {
      fail("Should not happen");
    }
  }

  static DirectoryStream<Path> directoryStream(List<Path> directoryItems) {
    DirectoryStream<Path> stream = mock(DirectoryStream.class);
    given(stream.iterator()).will(inv -> directoryItems.iterator());
    given(stream.spliterator()).will(inv -> Spliterators.spliteratorUnknownSize(directoryItems.iterator(), 0));
    return stream;
  }

  private DirectoryStream<Path> filterStream(Predicate<Path> filter, DirectoryStream<Path> source) throws IOException {
    DirectoryStream<Path> stream = mock(DirectoryStream.class);
    given(stream.iterator()).will(inv -> Iterators.filter(source.iterator(), filter::test));
    given(stream.spliterator()).will(inv -> Spliterators.spliteratorUnknownSize(Iterators.filter(source.iterator(), filter::test), 0));
    willAnswer(inv -> {
      source.close();
      return null;
    }).given(stream).close();
    return stream;
  }

  static Path mockPath(String... names) {
    Path path = mock(Path.class);
    given(path.toString()).willReturn(Strings.join(names).with(File.separator));
    if (names.length > 1) {
      Path filename = mockPath(names[names.length - 1]);
      given(path.getFileName()).willReturn(filename);
      given(path.getParent()).will(inv -> mockPath(Arrays.copyOf(names, names.length - 1)));
    } else {
      given(path.getFileName()).willReturn(path);
      given(path.getParent()).willReturn(null);
    }
    given(path.getNameCount()).willReturn(names.length);
    given(path.getName(anyInt())).will(inv -> names[(int) inv.getArgument(0)]);
    return path;
  }

  Path mockRegularFile(String... names) {
    Path path = mockPath(names);
    given(nioFilesWrapper.exists(path)).willReturn(true);
    given(nioFilesWrapper.isRegularFile(path)).willReturn(true);
    try {
      given(nioFilesWrapper.newInputStream(path)).willReturn(new ByteArrayInputStream(new byte[0]));
    } catch (IOException e) {
      fail("Should not happen");
    }
    return path;
  }

  Path mockDirectory(String name, DirectoryStream<Path> directoryItems) {
    Path path = mockPath(name);
    given(nioFilesWrapper.exists(path)).willReturn(true);
    given(nioFilesWrapper.isDirectory(path)).willReturn(true);
    try {
      given(nioFilesWrapper.newDirectoryStream(eq(path), any())).will(inv -> filterStream(inv.getArgument(1), directoryItems));
    } catch (IOException e) {
      fail("Should not happen");
    }
    return path;
  }

  Path mockDirectory(String name, List<Path> paths) {
    DirectoryStream<Path> directoryItems = directoryStream(paths);
    Path path = mockPath(name);
    given(nioFilesWrapper.exists(path)).willReturn(true);
    given(nioFilesWrapper.isDirectory(path)).willReturn(true);
    try {
      given(nioFilesWrapper.newDirectoryStream(eq(path), any())).will(inv -> filterStream(inv.getArgument(1), directoryItems));
    } catch (IOException e) {
      fail("Should not happen");
    }
    return path;
  }
}


text:
<?php

namespace Chrisguitarguy\Plot;

class userDefinedFunctionsTest extends AcceptTestCase
{
    public function testUserFunctionWithEmptyParameterListEvalutesReturnValue()
    {
        $result = $this->execute('((lambda () 1))');
        $this->assertEquals(1, $result);
    }

    public function testUserFunctionWithParameterPassesParametersFromCall()
    {
        $result = $this->execute('((lambda (x) x) 2)');
        $this->assertEquals(2, $result);
    }

    public function testUserFunctionsCanBeReusedFurtherOnInTheScript()
    {
        $result = $this->execute('(define fn (lambda () true)) (fn)');
        $this->assertTrue($result);
    }

    public function testUserFunctionsCanBeRecursive()
    {
        $prog ="
        (define fn (lambda (countdown) (if (<= countdown 0) 'boom' (recur (- countdown 1)))))
        (fn 10)";

        $result = $this->execute($prog);
        $this->assertEquals('boom', $result);
    }

    public function testUserFunctionsCanBeReasigned()
    {
        $prog ="
        (define fn (lambda (countdown) (if (<= countdown 0) 'boom' (recur (- countdown 1)))))
        (define fn2 fn)
        (fn2 10)";

        $result = $this->execute($prog);
        $this->assertEquals('boom', $result);
    }

    /**
     * @expectedException Chrisguitarguy\Plot\Exception\BadCallException
     */
    public function testUserFunctionCallWithToFewArgumentsCausesError()
    {
        $this->execute('((lambda (x) x))');
    }

    /**
     * @expectedException Chrisguitarguy\Plot\Exception\BadCallException
     */
    public function testUserFunctionCallWithToManyArgumentsCausesError()
    {
        $this->execute('((lambda (x) x) "one" "two")');
    }
}


text:
from django.shortcuts import render
from django.views.generic import ListView
from .models import CvsHistory, Engineer, Jira
from django.http import HttpResponse
from django.views.generic import View
from django.shortcuts import render_to_response
from django.core.paginator import Paginator,InvalidPage,EmptyPage,PageNotAnInteger

# Create your views here.

RECORDS_PER_PAGE = 10
RECORDS_PER_LISTPAGE = 50

def get_page(objs, page, perpage=RECORDS_PER_LISTPAGE):
    paginator = Paginator(objs, perpage)

    try:
        ret = paginator.page(page)
    except (EmptyPage, InvalidPage):
        ret = paginator.page(paginator.num_pages)

    return ret

def getEngineerMap():
    # Add in a QuerySet
    EngineerList = Engineer.objects.all()
    EngineerMap = {}
    for engineer in EngineerList:
        cvs_name = engineer.cvs_name
        EngineerMap[cvs_name] = engineer.name

    return EngineerMap

def add_page_range_to_context(context, show_pages=10):
    page_obj = context['page_obj']
    current_page = page_obj.number
    print current_page
    total_pages = page_obj.paginator.num_pages
    print total_pages
    show_page_range = range(1, show_pages + 1)
    if total_pages <= show_pages:
        show_page_range = range(1, total_pages+1)
    else:
        if current_page <= (show_pages / 2):
            show_page_range = range(1, show_pages+1)
        elif current_page > total_pages - (show_pages / 2):
            show_page_range = range(total_pages - show_pages, total_pages+1)
        else:
            show_page_range = range(current_page - (show_pages / 2), current_page + (show_pages / 2))

    context['show_page_range'] = show_page_range
    context['page_obj'] = page_obj

class CvsHistoryList(ListView):
    model = CvsHistory
    paginate_by = 50
    template_name = 'cvs_history/cvshistory_list.html'

    def get_context_data(self, **kwargs):
        # Call the base implementation first to get a context
        context = super(CvsHistoryList, self).get_context_data(**kwargs)
        # Add in a QuerySet
        context['engineer_map'] = getEngineerMap()
        add_page_range_to_context(context)
        return context

class CvsHistoryAuthorList(ListView):
    model = CvsHistory
    template_name = 'cvs_history/cvshistoryauthor_list.html'

    def get_queryset(self):
        author = self.args[0]
        try:
            page = int(self.args[1])
        except:
            page = 1
        return get_page(CvsHistory.objects.filter(author=author), page)

class LastTenJiraView(View):

    def get(self, request, *args, **kwargs):
        try:
            page = int(self.args[0])
        except:
            page = 1
        #print "class LastTenJiraView(View): page=", page
        tempResult = get_page(Jira.objects.all(), page, 10)
        #print "len(result)=", len(tempResult)

        LastTenJiraList = []
        for item in tempResult.object_list:
            jiraId = str(item.name)
            #print jiraId
            jira = {}
            jira['id'] = jiraId.upper()
            jiraItems = CvsHistory.objects.filter(jira=jiraId)
            jiraFiles = []

            for jiraItem in jiraItems:
                file = jiraItem.file
                if file not in jiraFiles:
                    jiraFiles.append(file)

            jiraFiles.sort()
            jira['author'] = item.author
            jira['files'] = jiraFiles
            jira['lastUpdate'] = item.first_update
            jira['firstUpdate'] = item.last_update
            LastTenJiraList.append(jira)
            tempResult.object_list = LastTenJiraList

        return render_to_response('cvs_history/jira_list.html',
                                  {'jiraList': tempResult,
                                   'engineer_map': getEngineerMap()
                                  })

class JiraList(ListView):
    model = Jira
    template_name = 'cvs_history/jiralist_list.html'

    def get_queryset(self):
        return Jira.objects.all()[0:100]

    def get_context_data(self, **kwargs):
        # Call the base implementation first to get a context
        context = super(JiraList, self).get_context_data(**kwargs)
        context['engineer_map'] = getEngineerMap()
        return context

class JiraView(View):
    """
    Query a jira info
    """
    def get(self, request, *args, **kwargs):
        jira_id = args[0]
        EngineerList = Engineer.objects.all()
        EngineerMap = {}
        for engineer in EngineerList:
            cvs_name = engineer.cvs_name
            EngineerMap[cvs_name] = engineer

        Jira = {}
        Jira['id'] = jira_id.upper()
        jiraItems =  CvsHistory.objects.filter(jira=jira_id)
        jiraAuthors = []
        jiraFiles = []
        jiraLastUpdate = None
        jiraFirstUpdate = None
        for jiraItem in jiraItems:
            author = jiraItem.author
            if EngineerMap.has_key(author):
                author = EngineerMap[author].name
            if author not in jiraAuthors:
                jiraAuthors.append(author)
            file = jiraItem.file
            if file not in jiraFiles:
                jiraFiles.append(file)
            updateTime = jiraItem.updatetime
            if jiraLastUpdate == None or jiraLastUpdate < updateTime:
                jiraLastUpdate = updateTime
            if jiraFirstUpdate == None or jiraFirstUpdate > updateTime:
                jiraFirstUpdate = updateTime

        jiraFiles.sort()
        Jira['authors'] = jiraAuthors
        Jira['files'] = jiraFiles
        Jira['lastUpdate'] = jiraLastUpdate
        Jira['firstUpdate'] = jiraFirstUpdate
        return render_to_response('cvs_history/jira_detail.html', {'jira': Jira})


text:
[![Build Status](https://travis-ci.org/basis-stack/basis.svg?branch=master)](https://travis-ci.org/basis-stack/basis)
[![Build status](https://ci.appveyor.com/api/projects/status/y9frdmgti2eujjyd?svg=true)](https://ci.appveyor.com/project/justinware/basis)
[![Coverage Status](https://coveralls.io/repos/github/basis-stack/basis/badge.svg?branch=master)](https://coveralls.io/github/basis-stack/basis?branch=master)
[![Code Climate](https://codeclimate.com/github/basis-stack/basis/badges/gpa.svg)](https://codeclimate.com/github/basis-stack/basis)

## What ?
**TL;DR**: Node.js + ES6/TS + React project setup & framework pieces that forms the ***basis*** of next-gen, dependable, testable, scalable, amazing JavaScript applications. Work in Progress.

Basis is a full-stack ES6 or TypeScript application project setup + framework elements for creating highly testable, robust, easy to scale, nice to use, feature focused, deploy-ready JavaScript applications. It combines both server & client code structure and framework elements (client / server mutually exclusive), and also build chain concerns in order to minimise boilerplate, bury repetitive setup and noise, bury build chain, bury productionisation concerns, bury wire-up, bury runtime and allow the application creator solely to focus on the good stuff, the timely and easy horizontal feature scale out.

Basis is **NOT** just another application quick starter / template / etc a la create-react-app or others, it can do that job if that's the sole desire…but it's goals, approach and reasoning is much more holistic that simply booting up a quick app.

In essence, Basis is a best-practice JavaScript stack…it is not a framework…nor a sole template. It combines the best of those approaches to pull together best-of-breed, prevalent, high-usage JavaScript libraries across the server, client (UI) and build tiers into a single full-stack offering for creating scalable and dependable applications.

At its core is an ethos of quality…quality code, quality testing, quality experience (be that in the server API, UI or even build chain experience) and is designed to create structured, large JavaScript apps.

Basis supports the following application modes:

* Server – ES6 – Defined (opt-in) structure. Express.js based
* Server – ES6 – Freeform. Raw app.js, no frameworks
* Server – TypeScript - Defined (opt-in) structure. Express.js based
* Server – TypeScript - Freeform. Raw app.ts, no frameworks
* Client - ES6 – Defined (opt-in) structure. React/Redux based
* Client - ES6 – Freeform. Raw index.js, no frameworks
* Client - TypeScript – Defined (opt-in) structure. React/Redux based
* Client - TypeScript – Freeform. Raw index.ts, no frameworks
* Plus an ES or TypeScript Monorepo setup for shared libraries (npm packages).

The Server and Client do not need to be used together, they can utilised mutually exclusively. Basis supports Server only (API / WebSockets), Client only (WebPack Bundle) or both. It's entirely up to application creators how the stack is used.

Similar to create-react-app and others, Basis also supports a zero-config approach for both the Server and Client, applying sound defaults to allow creators to get up and running quickly with minimum fuss. Opt-in config options can then be layered on to the defaults as and when needed.

Basis is currently being used for personal projects, and has been used in the enterprise across a wide variety of applications in both ES6 and TypeScript flavours.

## Why ?
**TL;DR**: Quality, testability, reduce boilerplate, bury non-feature concerns, great UX, scalable, production ready.

### Goals

The 10 core pillars of Basis:

* 100% (unit) testable - Reliable, dependable code...always
* ES6 / ES7 / ESNext or TypeScript as 1st-class concern
* (True) Production Ready - Including logging, multi-environment support, security, robustness, etc
* Push-button deployable - Deploy to PROD from initial clone
* Minimum Boilerplate - Minimum boilerplate / repetitive setup code / config from server, to build chain, to client (from project to project)
* Ease of Use (UX) - Easy to get up and running, easy to consume, easy to scale features, easy to deploy
* Versatile / Scalable - Can be used as true *basis* of everything, from static websites to complex enterprise applications
* Modular - Both in architecture (stack / npm packages), and in features from server to client
* Great UX - For everything...from Rest APIs, to errors, to logs, to build-chain, to deploys, to UI
* Enjoyable - Must be fun to use and build apps with

With secondary goals being:

* Dogfooding - Everything that *can* be built with Basis *is* built with Basis.
* Extension - Easy to extend architecture for complex cases, easy to add core modules
* Performant - Everything from server, to build chain, to client is snappy and responsive

Full Why / Background coming soon…

## How ?
**TL;DR**: Clone the repo, then:

yarn:
```sh
$ yarn
$ yarn link:packages
$ yarn build
$ yarn start
```

npm:
```sh
$ npm install
$ npm run link:packages
$ npm run build
$ npn run start
```

This will spin up both the Server & UI from this Monorepo setup, linking the nested npm packages (Basis framework packages).

***Note**: This is not normally how an application creator would use this stack, it is highlighted here for demonstration purposes only.*

This Monorepo setup is used as the core development platform so that framework pieces can be worked on and tested together in the broader context of the template. I.e. This repo is a dev only reference, not a ready to go template.

Going forward separate application templates for each of the supported application modes will be created (sans framework packages) and given their own repos inside the Basis Stack org, and creators will then simply clone & tweak the appropriate template. This is very much a work in progress.

There is also a CLI / generator in the pipeline a la express generator that will do this template-specific cloning for the application creator via targeted questions and then apply a few smarts / tweaks to cloned template to be app-specific and spin-up ready.

Full How / Setups / Config options, etc coming soon…

## Who ?

Basis is and has been the passion project of Justin Ware, who serves as founder and project lead, and who has endeavoured to bring about a structured, repeatable and (Software Engineering) best practice approach to building large scale JavaScript applications ever since diverging from the fullstack .NET world a few years ago.

There is a ginormous amount of pipeline work still to do to get it where it needs to be, so **collaborators & PRs are absolutely welcome !!**