text:
package org.fcrepo.kernel.impl;

import org.fcrepo.kernel.api.Transaction;
import org.fcrepo.kernel.api.exception.RepositoryRuntimeException;
import org.fcrepo.kernel.api.identifiers.FedoraId;
import org.fcrepo.kernel.api.models.FedoraResource;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.inject.Inject;
import java.util.HashMap;
import java.util.Map;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.when;

import java.util.UUID;

/**
 * @author peichman
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/containmentIndexTest.xml")
public class ContainmentIndexImplTest {
    @Mock
    private FedoraResource parent1;

    @Mock
    private FedoraResource child1;

    @Mock
    private FedoraResource parent2;

    @Mock
    private FedoraResource child2;

    @Mock
    private Transaction transaction1;

    @Mock
    private Transaction transaction2;

    @Inject
    private ContainmentIndexImpl containmentIndex;

    @Rule
    public MockitoRule rule = MockitoJUnit.rule();

    private Map<String, FedoraResource> id_to_resource = new HashMap<>();
    private Map<String, Transaction> id_to_transaction = new HashMap<>();

    @Before
    public void setUp() {
        id_to_resource.put("parent1", parent1);
        id_to_resource.put("parent2", parent2);
        id_to_resource.put("child1", child1);
        id_to_resource.put("child2", child2);
        id_to_transaction.put("transaction1", transaction1);
        id_to_transaction.put("transaction2", transaction2);
    }

    /**
     * Utility method to make it easier to stub the getFedoraId() method and avoid MockitoHints.
     * @param id The resource|transaction ID/name
     */
    private void stubObject(final String id) {
        // Use unique ids for resources and transactions.
        final String uuid = UUID.randomUUID().toString();
        if (id_to_resource.containsKey(id)) {
            final FedoraId fID = FedoraId.create(uuid);
            when(id_to_resource.get(id).getFedoraId()).thenReturn(fID);
        } else if (id_to_transaction.containsKey(id)) {
            when(id_to_transaction.get(id).getId()).thenReturn(uuid);
        }
    }

    @After
    public void cleanUp() {
        // Rollback any in-process transactions.
        containmentIndex.rollbackTransaction(transaction1.getId());
        containmentIndex.rollbackTransaction(transaction2.getId());
    }

    @Test
    public void testAddChildInTransaction() {
        stubObject("parent1");
        stubObject("child1");
        stubObject("transaction1");
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(child1.getFedoraId().getFullId(),
                containmentIndex.getContains(transaction1.getId(), parent1).findFirst().get());
        assertEquals(parent1.getFedoraId().getFullId(),
                containmentIndex.getContainedBy(transaction1.getId(), child1.getFedoraId()));
        // outside of the transaction, the containment shouldn't show up
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        containmentIndex.removeContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        assertEquals(0, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertNull(containmentIndex.getContainedBy(transaction1.getId(), child1.getFedoraId()));
    }

    @Test
    public void testAddRemoveChildInSameTransaction() {
        stubObject("parent1");
        stubObject("child1");
        stubObject("transaction1");
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertEquals(0, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(0, containmentIndex.getContainsDeleted(null, parent1).count());
        assertEquals(0, containmentIndex.getContainsDeleted(transaction1.getId(), parent1).count());
        assertNull(containmentIndex.getContainedBy(transaction1.getId(), child1.getFedoraId()));
        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(parent1.getFedoraId().getFullId(),
                containmentIndex.getContainedBy(transaction1.getId(), child1.getFedoraId()));
        containmentIndex.removeContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        assertEquals(0, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertNull(containmentIndex.getContainedBy(transaction1.getId(), child1.getFedoraId()));
        assertEquals(0, containmentIndex.getContainsDeleted(null, parent1).count());
        assertEquals(0, containmentIndex.getContainsDeleted(transaction1.getId(), parent1).count());
    }

    @Test
    public void testAddRemoveChildInTwoTransactions() {
        stubObject("parent1");
        stubObject("child1");
        stubObject("transaction1");
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertEquals(0, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(0, containmentIndex.getContainsDeleted(null, parent1).count());
        assertEquals(0, containmentIndex.getContainsDeleted(transaction1.getId(), parent1).count());
        assertNull(containmentIndex.getContainedBy(transaction1.getId(), child1.getFedoraId()));
        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(parent1.getFedoraId().getFullId(),
                containmentIndex.getContainedBy(transaction1.getId(), child1.getFedoraId()));
        containmentIndex.commitTransaction(transaction1.getId());
        assertEquals(1, containmentIndex.getContains(null, parent1).count());
        containmentIndex.removeContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        assertEquals(0, containmentIndex.getContainsDeleted(null, parent1).count());
        assertEquals(1, containmentIndex.getContainsDeleted(transaction1.getId(), parent1).count());
        assertEquals(0, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertNull(containmentIndex.getContainedBy(transaction1.getId(), child1.getFedoraId()));
        containmentIndex.commitTransaction(transaction1.getId());
        assertEquals(1, containmentIndex.getContainsDeleted(null, parent1).count());
        assertEquals(1, containmentIndex.getContainsDeleted(transaction1.getId(), parent1).count());
    }

    @Test
    public void testAddRemovePurgeChildInTransaction() {
        stubObject("parent1");
        stubObject("child1");
        stubObject("transaction1");
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertEquals(0, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(0, containmentIndex.getContainsDeleted(null, parent1).count());
        assertNull(containmentIndex.getContainedBy(transaction1.getId(), child1.getFedoraId()));
        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent1).count());
        containmentIndex.removeContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertEquals(0, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(0, containmentIndex.getContainsDeleted(null, parent1).count());
        assertEquals(0, containmentIndex.getContainsDeleted(transaction1.getId(), parent1).count());
        containmentIndex.purgeResource(transaction1.getId(), child1.getFedoraId());
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertEquals(0, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(0, containmentIndex.getContainsDeleted(null, parent1).count());
        assertEquals(0, containmentIndex.getContainsDeleted(transaction1.getId(), parent1).count());
    }

    @Test
    public void testAddRemovePurgeChildThreeTransaction() {
        stubObject("parent1");
        stubObject("child1");
        stubObject("transaction1");
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertEquals(0, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(0, containmentIndex.getContainsDeleted(null, parent1).count());
        assertNull(containmentIndex.getContainedBy(transaction1.getId(), child1.getFedoraId()));
        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        containmentIndex.commitTransaction(transaction1.getId());
        assertEquals(1, containmentIndex.getContains(null, parent1).count());
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent1).count());
        containmentIndex.removeContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        containmentIndex.commitTransaction(transaction1.getId());
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertEquals(0, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(1, containmentIndex.getContainsDeleted(null, parent1).count());
        assertEquals(1, containmentIndex.getContainsDeleted(transaction1.getId(), parent1).count());
        containmentIndex.purgeResource(transaction1.getId(), child1.getFedoraId());
        containmentIndex.commitTransaction(transaction1.getId());
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertEquals(0, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(0, containmentIndex.getContainsDeleted(null, parent1).count());
        assertEquals(0, containmentIndex.getContainsDeleted(transaction1.getId(), parent1).count());
    }

    @Test
    public void testRollbackTransaction() {
        stubObject("parent1");
        stubObject("child1");
        stubObject("transaction1");
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertEquals(0, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertNull(containmentIndex.getContainedBy(null, child1.getFedoraId()));
        assertNull(containmentIndex.getContainedBy(transaction1.getId(), child1.getFedoraId()));
        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(child1.getFedoraId().getFullId(),
                containmentIndex.getContains(transaction1.getId(), parent1).findFirst().get());
        assertNull(containmentIndex.getContainedBy(null, child1.getFedoraId()));
        assertEquals(parent1.getFedoraId().getFullId(),
                containmentIndex.getContainedBy(transaction1.getId(), child1.getFedoraId()));
        containmentIndex.rollbackTransaction(transaction1.getId());
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertEquals(0, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertNull(containmentIndex.getContainedBy(null, child1.getFedoraId()));
        assertNull(containmentIndex.getContainedBy(transaction1.getId(), child1.getFedoraId()));
    }

    @Test
    public void testCommitTransaction() {
        stubObject("parent1");
        stubObject("child2");
        stubObject("transaction1");
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertEquals(0, containmentIndex.getContains(transaction1.getId(), parent1).count());
        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child2.getFedoraId());
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(child2.getFedoraId().getFullId(),
                containmentIndex.getContains(transaction1.getId(), parent1).findFirst().get());
        assertEquals(parent1.getFedoraId().getFullId(),
                containmentIndex.getContainedBy(transaction1.getId(), child2.getFedoraId()));
        assertNull(containmentIndex.getContainedBy(null, child2.getFedoraId()));
        containmentIndex.commitTransaction(transaction1.getId());
        assertEquals(1, containmentIndex.getContains(null, parent1).count());
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(child2.getFedoraId().getFullId(),
                containmentIndex.getContains(null, parent1).findFirst().get());
        assertEquals(parent1.getFedoraId().getFullId(),
                containmentIndex.getContainedBy(transaction1.getId(), child2.getFedoraId()));
        assertEquals(child2.getFedoraId().getFullId(),
                containmentIndex.getContains(transaction1.getId(), parent1).findFirst().get());
        assertEquals(parent1.getFedoraId().getFullId(),
                containmentIndex.getContainedBy(null, child2.getFedoraId()));
    }

    @Test
    public void testSwapContained() {
        stubObject("parent1");
        stubObject("child1");
        stubObject("child2");
        stubObject("transaction1");
        stubObject("transaction2");
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        containmentIndex.commitTransaction(transaction1.getId());
        assertEquals(1, containmentIndex.getContains(null, parent1).count());
        assertEquals(child1.getFedoraId().getFullId(),
                containmentIndex.getContains(null, parent1).findFirst().get());
        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child2.getFedoraId());
        containmentIndex.removeContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        // Still the same outside
        assertEquals(1, containmentIndex.getContains(null, parent1).count());
        assertEquals(child1.getFedoraId().getFullId(),
                containmentIndex.getContains(null, parent1).findFirst().get());
        // Still the same in a different transaction
        assertEquals(1, containmentIndex.getContains(transaction2.getId(), parent1).count());
        assertEquals(child1.getFedoraId().getFullId(),
                containmentIndex.getContains(transaction2.getId(), parent1).findFirst().get());
        // Inside it has changed
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(child2.getFedoraId().getFullId(),
                containmentIndex.getContains(transaction1.getId(), parent1).findFirst().get());
        containmentIndex.commitTransaction(transaction1.getId());
        // After commit() it is the same outside transactions.
        assertEquals(1, containmentIndex.getContains(null, parent1).count());
        assertEquals(child2.getFedoraId().getFullId(),
                containmentIndex.getContains(null, parent1).findFirst().get());
        // And now the same in a different transaction
        assertEquals(1, containmentIndex.getContains(transaction2.getId(), parent1).count());
        assertEquals(child2.getFedoraId().getFullId(),
                containmentIndex.getContains(transaction2.getId(), parent1).findFirst().get());
    }

    @Test
    public void testOnlyCommitOne() {
        stubObject("parent1");
        stubObject("child1");
        stubObject("child2");
        stubObject("transaction1");
        stubObject("transaction2");
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child2.getFedoraId());
        containmentIndex.commitTransaction(transaction1.getId());
        assertEquals(2, containmentIndex.getContains(null, parent1).count());
        // Delete one object in separate transactions.
        containmentIndex.removeContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        containmentIndex.removeContainedBy(transaction2.getId(), parent1.getFedoraId(), child2.getFedoraId());
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(1, containmentIndex.getContains(transaction2.getId(), parent1).count());
        containmentIndex.commitTransaction(transaction1.getId());
        // Now only one record was removed
        assertEquals(1, containmentIndex.getContains(null, parent1).count());
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent1).count());
        // Except in the second transaction as it should now have 0
        assertEquals(0, containmentIndex.getContains(transaction2.getId(), parent1).count());
        containmentIndex.commitTransaction(transaction2.getId());
        // Now all are gone
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertEquals(0, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(0, containmentIndex.getContains(transaction2.getId(), parent1).count());
    }

    @Test
    public void testTwoTransactionDeleteSameChild() {
        stubObject("parent1");
        stubObject("child1");
        stubObject("child2");
        stubObject("transaction1");
        stubObject("transaction2");
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child2.getFedoraId());
        containmentIndex.commitTransaction(transaction1.getId());
        assertEquals(2, containmentIndex.getContains(null, parent1).count());
        // Delete one object in separate transactions.
        containmentIndex.removeContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        containmentIndex.removeContainedBy(transaction2.getId(), parent1.getFedoraId(), child1.getFedoraId());
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(1, containmentIndex.getContains(transaction2.getId(), parent1).count());
        containmentIndex.commitTransaction(transaction1.getId());
        // Now only one record was removed
        assertEquals(1, containmentIndex.getContains(null, parent1).count());
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(1, containmentIndex.getContains(transaction2.getId(), parent1).count());
        containmentIndex.commitTransaction(transaction2.getId());
        // No change as the first transaction already committed.
        assertEquals(1, containmentIndex.getContains(null, parent1).count());
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(1, containmentIndex.getContains(transaction2.getId(), parent1).count());
    }

    @Test
    public void testContainedByTwoSameTransactionException() {
        stubObject("parent1");
        stubObject("parent2");
        stubObject("child1");
        stubObject("transaction1");
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertEquals(0, containmentIndex.getContains(null, parent2).count());
        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        containmentIndex.addContainedBy(transaction1.getId(), parent2.getFedoraId(), child1.getFedoraId());
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertEquals(0, containmentIndex.getContains(null, parent2).count());
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent2).count());
        try {
            containmentIndex.commitTransaction(transaction1.getId());
            // We should get an exception.
            fail();
        } catch (final RepositoryRuntimeException e) {
            // This was an expected exception. Now continue the test.
        }
        // This should be rolled back so the additions should still be in the transaction operation table.
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertEquals(0, containmentIndex.getContains(null, parent2).count());
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent1).count());
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent2).count());
    }

    @Test
    public void testExistsOutsideTransaction() {
        stubObject("parent1");
        stubObject("child1");
        stubObject("transaction1");
        stubObject("transaction2");
        assertFalse(containmentIndex.resourceExists(null, child1.getFedoraId()));
        assertFalse(containmentIndex.resourceExists(transaction1.getId(), child1.getFedoraId()));
        containmentIndex.addContainedBy(transaction2.getId(), parent1.getFedoraId(), child1.getFedoraId());
        containmentIndex.commitTransaction(transaction2.getId());
        assertTrue(containmentIndex.resourceExists(null, child1.getFedoraId()));
        assertTrue(containmentIndex.resourceExists(transaction1.getId(), child1.getFedoraId()));
    }

    @Test
    public void testExistsInsideTransaction() {
        stubObject("parent1");
        stubObject("child1");
        stubObject("transaction1");
        stubObject("transaction2");
        assertFalse(containmentIndex.resourceExists(null, child1.getFedoraId()));
        assertFalse(containmentIndex.resourceExists(transaction1.getId(), child1.getFedoraId()));
        assertFalse(containmentIndex.resourceExists(transaction2.getId(), child1.getFedoraId()));
        // Only visible in the transaction.
        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        assertFalse(containmentIndex.resourceExists(null, child1.getFedoraId()));
        assertTrue(containmentIndex.resourceExists(transaction1.getId(), child1.getFedoraId()));
        assertFalse(containmentIndex.resourceExists(transaction2.getId(), child1.getFedoraId()));
        // Rollback transaction.
        containmentIndex.rollbackTransaction(transaction1.getId());
        assertFalse(containmentIndex.resourceExists(null, child1.getFedoraId()));
        assertFalse(containmentIndex.resourceExists(transaction1.getId(), child1.getFedoraId()));
        assertFalse(containmentIndex.resourceExists(transaction2.getId(), child1.getFedoraId()));
        // Add again in transaction.
        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        assertFalse(containmentIndex.resourceExists(null, child1.getFedoraId()));
        assertTrue(containmentIndex.resourceExists(transaction1.getId(), child1.getFedoraId()));
        assertFalse(containmentIndex.resourceExists(transaction2.getId(), child1.getFedoraId()));
        // Commit and visible everywhere.
        containmentIndex.commitTransaction(transaction1.getId());
        assertTrue(containmentIndex.resourceExists(null, child1.getFedoraId()));
        assertTrue(containmentIndex.resourceExists(transaction1.getId(), child1.getFedoraId()));
        assertTrue(containmentIndex.resourceExists(transaction2.getId(), child1.getFedoraId()));
    }

    @Test
    public void testRemoveResource() {
        stubObject("parent1");
        stubObject("child1");
        stubObject("transaction1");
        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        containmentIndex.commitTransaction(transaction1.getId());
        assertEquals(1, containmentIndex.getContains(null, parent1).count());
        assertEquals(parent1.getFedoraId().getFullId(),
                containmentIndex.getContainedBy(null, child1.getFedoraId()));
        containmentIndex.removeResource(transaction1.getId(), child1.getFedoraId());
        containmentIndex.commitTransaction(transaction1.getId());
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertNull(containmentIndex.getContainedBy(null, child1.getFedoraId()));
    }

    @Test
    public void testRemoveNotFromTransaction() {
        stubObject("parent1");
        stubObject("child1");
        stubObject("parent2");
        stubObject("transaction1");
        stubObject("transaction2");
        assertNull(containmentIndex.getContainedBy(null, child1.getFedoraId()));
        containmentIndex.addContainedBy(transaction2.getId(), parent1.getFedoraId(), child1.getFedoraId());
        containmentIndex.commitTransaction(transaction2.getId());
        containmentIndex.addContainedBy(transaction1.getId(), parent2.getFedoraId(), child1.getFedoraId());
        assertEquals(1, containmentIndex.getContains(null, parent1).count());
        assertEquals(parent1.getFedoraId().getFullId(),
                containmentIndex.getContainedBy(null, child1.getFedoraId()));
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent2).count());
        assertEquals(child1.getFedoraId().getFullId(),
                containmentIndex.getContains(transaction1.getId(), parent2).findFirst().get());
        containmentIndex.removeResource(transaction2.getId(), child1.getFedoraId());
        containmentIndex.commitTransaction(transaction2.getId());
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertNull(containmentIndex.getContainedBy(null, child1.getFedoraId()));
        assertEquals(1, containmentIndex.getContains(transaction1.getId(), parent2).count());
        assertEquals(child1.getFedoraId().getFullId(),
                containmentIndex.getContains(transaction1.getId(), parent2).findFirst().get());
    }

    @Test
    public void testCommitRemoveFromTransaction() {
        stubObject("parent1");
        stubObject("child1");
        stubObject("parent2");
        stubObject("transaction1");
        stubObject("transaction2");
        containmentIndex.addContainedBy(transaction2.getId(), parent1.getFedoraId(), child1.getFedoraId());
        containmentIndex.commitTransaction(transaction2.getId());
        assertEquals(1, containmentIndex.getContains(null, parent1).count());
        assertEquals(parent1.getFedoraId().getFullId(),
                containmentIndex.getContainedBy(null, child1.getFedoraId()));
        containmentIndex.removeResource(transaction1.getId(), child1.getFedoraId());
        assertEquals(1, containmentIndex.getContains(null, parent1).count());
        assertEquals(parent1.getFedoraId().getFullId(),
                containmentIndex.getContainedBy(null, child1.getFedoraId()));
        assertEquals(0, containmentIndex.getContains(transaction1.getId(), parent1).count());
        containmentIndex.commitTransaction(transaction1.getId());
        assertEquals(0, containmentIndex.getContains(null, parent1).count());
        assertNull(containmentIndex.getContainedBy(null, child1.getFedoraId()));
        assertEquals(0, containmentIndex.getContains(transaction1.getId(), parent1).count());
    }

    /**
     * Ensure match the id without a trailing slash.
     */
    @Test
    public void testResourceExistsFedoraIDNoTrailingSlash() {
        stubObject("parent1");
        stubObject("child1");
        stubObject("transaction1");
        final FedoraId fedoraID = FedoraId.create(child1.getFedoraId().getFullId());
        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        containmentIndex.commitTransaction(transaction1.getId());
        assertEquals(1, containmentIndex.getContains(null, parent1).count());
        assertEquals(parent1.getFedoraId().getFullId(),
                containmentIndex.getContainedBy(null, child1.getFedoraId()));
        assertTrue(containmentIndex.resourceExists(null, child1.getFedoraId()));
        assertTrue(containmentIndex.resourceExists(null, fedoraID));
    }

    /**
     * Ensure match the id with a trailing slash.
     */
    @Test
    public void testResourceExistsFedoraIDTrailingSlash() {
        stubObject("parent1");
        stubObject("child1");
        stubObject("transaction1");
        final FedoraId fedoraID = FedoraId.create(child1.getFedoraId().getFullId() + "/");
        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());
        containmentIndex.commitTransaction(transaction1.getId());
        assertEquals(1, containmentIndex.getContains(null, parent1).count());
        assertEquals(parent1.getFedoraId().getFullId(),
                containmentIndex.getContainedBy(null, child1.getFedoraId()));
        assertTrue(containmentIndex.resourceExists(null, child1.getFedoraId()));
        assertTrue(containmentIndex.resourceExists(null, fedoraID));
    }

    @Test
    public void clearIndexWhenReset() {
        stubObject("parent1");
        stubObject("child1");
        stubObject("transaction1");

        containmentIndex.addContainedBy(transaction1.getId(), parent1.getFedoraId(), child1.getFedoraId());

        assertTrue(containmentIndex.resourceExists(transaction1.getId(), child1.getFedoraId()));

        containmentIndex.reset();

        assertFalse(containmentIndex.resourceExists(transaction1.getId(), child1.getFedoraId()));
    }

}


text:
FROM golang:1.12

ADD ./ /chi
WORKDIR /chi

RUN mkdir bin
ENV GOPATH /chi
ENV PATH ${GOPATH}/bin:${PATH}

RUN go get github.com/francoispqt/gojay
RUN go get github.com/jackc/pgx
RUN go get github.com/go-chi/chi

RUN go build -o server src/chi-gojay/*.go
CMD ./server

redpajama_set_name: RedPajamaGithub


text:
namespace PianoTiles
{
    partial class FrmGame
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.timer1 = new System.Windows.Forms.Timer(this.components);
            this.menuStrip1 = new System.Windows.Forms.MenuStrip();
            this.tsmFile = new System.Windows.Forms.ToolStripMenuItem();
            this.tsmRestart = new System.Windows.Forms.ToolStripMenuItem();
            this.tsmMainMenu = new System.Windows.Forms.ToolStripMenuItem();
            this.tsmTools = new System.Windows.Forms.ToolStripMenuItem();
            this.tsmResume = new System.Windows.Forms.ToolStripMenuItem();
            this.tsmPause = new System.Windows.Forms.ToolStripMenuItem();
            this.menuStrip1.SuspendLayout();
            this.SuspendLayout();
            //
            // timer1
            //
            this.timer1.Enabled = true;
            this.timer1.Interval = 5;
            this.timer1.Tick += new System.EventHandler(this.Timer1_Tick);
            //
            // menuStrip1
            //
            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.tsmFile,
            this.tsmTools});
            this.menuStrip1.Location = new System.Drawing.Point(0, 0);
            this.menuStrip1.Name = "menuStrip1";
            this.menuStrip1.Size = new System.Drawing.Size(514, 24);
            this.menuStrip1.TabIndex = 0;
            this.menuStrip1.Text = "menuStrip1";
            //
            // tsmFile
            //
            this.tsmFile.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.tsmRestart,
            this.tsmMainMenu});
            this.tsmFile.Name = "tsmFile";
            this.tsmFile.Size = new System.Drawing.Size(54, 20);
            this.tsmFile.Text = "Fichier";
            //
            // tsmRestart
            //
            this.tsmRestart.Name = "tsmRestart";
            this.tsmRestart.Size = new System.Drawing.Size(154, 22);
            this.tsmRestart.Text = "Recommencer";
            this.tsmRestart.Click += new System.EventHandler(this.MsRestart_Click);
            //
            // tsmMainMenu
            //
            this.tsmMainMenu.Name = "tsmMainMenu";
            this.tsmMainMenu.Size = new System.Drawing.Size(154, 22);
            this.tsmMainMenu.Text = "Menu principal";
            this.tsmMainMenu.Click += new System.EventHandler(this.TsmMainMenu_Click);
            //
            // tsmTools
            //
            this.tsmTools.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.tsmResume,
            this.tsmPause});
            this.tsmTools.Name = "tsmTools";
            this.tsmTools.Size = new System.Drawing.Size(50, 20);
            this.tsmTools.Text = "Outils";
            //
            // tsmResume
            //
            this.tsmResume.Name = "tsmResume";
            this.tsmResume.Size = new System.Drawing.Size(159, 22);
            this.tsmResume.Text = "Reprendre";
            this.tsmResume.Click += new System.EventHandler(this.TsmResume_Click);
            //
            // tsmPause
            //
            this.tsmPause.Name = "tsmPause";
            this.tsmPause.Size = new System.Drawing.Size(159, 22);
            this.tsmPause.Text = "Mettre en pause";
            this.tsmPause.Click += new System.EventHandler(this.TsmPause_Click);
            //
            // FrmGame
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(514, 531);
            this.Controls.Add(this.menuStrip1);
            this.DoubleBuffered = true;
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.MainMenuStrip = this.menuStrip1;
            this.MaximizeBox = false;
            this.Name = "FrmGame";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "Wall Piano Tiles";
            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FrmGame_FormClosing);
            this.Load += new System.EventHandler(this.FrmGame_Load);
            this.menuStrip1.ResumeLayout(false);
            this.menuStrip1.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Timer timer1;
        private System.Windows.Forms.MenuStrip menuStrip1;
        private System.Windows.Forms.ToolStripMenuItem tsmFile;
        private System.Windows.Forms.ToolStripMenuItem tsmRestart;
        private System.Windows.Forms.ToolStripMenuItem tsmMainMenu;
        private System.Windows.Forms.ToolStripMenuItem tsmTools;
        private System.Windows.Forms.ToolStripMenuItem tsmPause;
        private System.Windows.Forms.ToolStripMenuItem tsmResume;
    }
}


text:
require_relative '../../lib/zebris/types'
require 'date'

describe Zebris::Types do
  context Zebris::Types::Date do
    it "deserializes a valid date" do
      d = Date.today
      expect(Zebris::Types::Date.deserialize(d.to_s)).to eq(d)
    end

    it "raises an exception if the date is invalid" do
      d = ""
      expect{Zebris::Types::Date.deserialize(d.to_s)}.to raise_exception
    end
  end

  context Zebris::Types::Integer do
    it "deserializes a valid integer" do
      i = 101
      expect(Zebris::Types::Integer.deserialize(i.to_s)).to eq(i)
    end

    it "returns nil if the integer is an empty string" do
      i = ""
      expect(Zebris::Types::Integer.deserialize(i.to_s)).to eq(nil)
    end

    it "returns nil if the integer is nil" do
      i = nil
      expect(Zebris::Types::Integer.deserialize(i)).to eq(nil)
    end

    it "raises an exception if the object does not support being converted to an integer" do
      o = Object.new
      expect{Zebris::Types::Integer.deserialize(o)}.to raise_exception
    end
  end

  context Zebris::Types::Float do
    it "deserializes and returns serialized float" do
      f = 10.23
      expect(Zebris::Types::Float.deserialize(f.to_s)).to eq(f)
    end

    it "deserializes and returns nil on an empty string" do
      f = ""
      expect(Zebris::Types::Float.deserialize(f.to_s)).to eq(nil)
    end

    it "deserializes and returns nil on an empty string" do
      f = nil
      expect(Zebris::Types::Float.deserialize(f)).to eq(nil)
    end

    it "raises an exception if the object does not support being converted to a float" do
      o = Object.new
      expect{Zebris::Types::Float.deserialize(o)}.to raise_exception
    end
  end
end


text:
package com.nguyenmp.starclient.test;

import com.nguyenmp.starclient.STAR;
import com.nguyenmp.starclient.XMLParser;
import org.junit.Assert;
import org.junit.Test;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;

public class STAR_Test {
	@Test
	public void login_Test() throws IOException, XMLParser.XMLException {
		Scanner scanner = new Scanner(new FileInputStream("credentials.conf"));
		String username = scanner.nextLine();
		String password = scanner.nextLine();

		//TODO: Write realistic test for logging in
		Assert.assertEquals(STAR.login(username, password), null);
	}
}


text:
#define COBJMACROS

#include "config.h"

#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "ole2.h"

#include "gameux.h"
#include "gameux_private.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(gameux);

typedef HRESULT (*fnCreateInstance)(IUnknown *pUnkOuter, IUnknown **ppObj);

/***************************************************************
 * gameux ClassFactory
 */
typedef struct _gameuxcf
{
    IClassFactory IClassFactory_iface;
    fnCreateInstance pfnCreateInstance;
} gameuxcf;

static inline gameuxcf *impl_from_IClassFactory(IClassFactory *iface)
{
    return CONTAINING_RECORD(iface, gameuxcf, IClassFactory_iface);
}

static HRESULT WINAPI gameuxcf_QueryInterface(
        IClassFactory *iface,
        REFIID riid,
        LPVOID *ppObj)
{
    TRACE("(%p, %s, %p)\n", iface, debugstr_guid(riid), ppObj);

    *ppObj = NULL;

    if(IsEqualGUID(riid, &IID_IUnknown) ||
       IsEqualGUID(riid, &IID_IClassFactory))
    {
        IClassFactory_AddRef(iface);
        *ppObj = iface;
        return S_OK;
    }

    FIXME("interface %s not implemented\n", debugstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI gameuxcf_AddRef(
        IClassFactory *iface)
{
    TRACE("(%p)\n", iface);
    return 2;
}

static ULONG WINAPI gameuxcf_Release(
        IClassFactory *iface)
{
    TRACE("(%p)\n", iface);
    return 1;
}

static HRESULT WINAPI gameuxcf_CreateInstance(
        IClassFactory *iface,
        LPUNKNOWN pUnkOuter,
        REFIID riid,
        LPVOID *ppObj)
{
    gameuxcf *This = impl_from_IClassFactory(iface);
    HRESULT hr;
    IUnknown *pUnk;

    TRACE("(%p, %p, %s, %p)\n", iface, pUnkOuter, debugstr_guid(riid), ppObj);

    *ppObj = NULL;

    if(pUnkOuter)
        return CLASS_E_NOAGGREGATION;

    hr = This->pfnCreateInstance(pUnkOuter, &pUnk);
    if(FAILED(hr))
        return hr;

    hr = IUnknown_QueryInterface(pUnk, riid, ppObj);
    IUnknown_Release(pUnk);
    return hr;
}

static HRESULT WINAPI gameuxcf_LockServer(
        IClassFactory *iface,
        BOOL dolock)
{
    gameuxcf *This = impl_from_IClassFactory(iface);
    TRACE("(%p, %d)\n", This, dolock);
    FIXME("stub\n");
    return S_OK;
}

static const struct IClassFactoryVtbl gameuxcf_vtbl =
{
    gameuxcf_QueryInterface,
    gameuxcf_AddRef,
    gameuxcf_Release,
    gameuxcf_CreateInstance,
    gameuxcf_LockServer
};

static gameuxcf gameexplorercf = { { &gameuxcf_vtbl }, GameExplorer_create };
static gameuxcf gamestatisticscf  = { { &gameuxcf_vtbl }, GameStatistics_create };

/***************************************************************
 * gameux ClassFactory
 */
HRESULT WINAPI DllGetClassObject(
        REFCLSID rclsid,
        REFIID riid,
        LPVOID *ppv)
{
    IClassFactory *cf = NULL;

    TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);

    if(IsEqualCLSID(rclsid, &CLSID_GameExplorer))
    {
        cf = &gameexplorercf.IClassFactory_iface;
    }
    else if( IsEqualCLSID( rclsid, &CLSID_GameStatistics ))
    {
        cf = &gamestatisticscf.IClassFactory_iface;
    }

    if(!cf)
        return CLASS_E_CLASSNOTAVAILABLE;

    return IClassFactory_QueryInterface(cf, riid, ppv);
}


text:
import Vue from "vue";
import App from "./App.vue";
import VueRs from "@appbaseio/reactivesearch-vue";

Vue.use(VueRs);
Vue.config.productionTip = false;

new Vue({
  render: h => h(App)
}).$mount("#app");


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using System.Collections;

namespace StringParsingLibrary.Tests
{
    [TestFixture]
    public class ParseEvenIntegersTests
    {
        [Test, Combinatorial]
        public void ParseEvenIntegersTests_OneValue(
            [Values("2")] string input)
        {
            var newInput = input;
            var matches = new ParseEvenIntegers(newInput);
            var list = matches.ToList();
            Assert.AreEqual(1, list.Count, "Value Tested:{0}", newInput);
            Assert.AreEqual(2, list[0]);
        }

        [Test, Combinatorial]
        public void ParseEvenIntegersTests_OneValue_Padding(
            [Values("2")] string input,
            [Values("", " ", "  ")] string frontPadding,
            [Values("", " ", " ")] string backPadding)
        {
            var padding = new string(' ', 10);
            var newInput = frontPadding + input + backPadding;
            var matches = new ParseEvenIntegers(newInput);
            var list = matches.ToList();
            Assert.AreEqual(1, list.Count, "Value Tested:{0}", newInput);
            Assert.AreEqual(2, list[0]);
        }

        public class multilineCases_one_value : IEnumerable
        {
            public IEnumerator GetEnumerator()
            {
                return new List<string> {
@"1 1 1 dsafadfa
uujj
0
2",
@"0

2
1  dadf 1" }.GetEnumerator();
            }
        }

        [Test]
        [TestCaseSource(typeof(multilineCases_one_value))]
        public void ParseEvenIntegersTests_multilineCases_one_value(string input)
        {
            var matches = new ParseEvenIntegers(input);
            var list = matches.ToList();
            Assert.AreEqual(2, list.Count);

            Assert.AreEqual(0, list[0]);
            Assert.AreEqual(2, list[1]);
        }

        public class multilineCases_two_values : IEnumerable
        {
            public IEnumerator GetEnumerator()
            {
                return new List<string> {
@" 0
 2 ",
@" 0
s
 2",
@"0
        0-

 2"
}.GetEnumerator();
            }
        }

        [Test]
        [TestCaseSource(typeof(multilineCases_two_values))]
        public void ParseEvenIntegersTests_multilineCases_two_value(string input)
        {
            var matches = new ParseEvenIntegers(input);
            var list = matches.ToList();
            Assert.AreEqual(2, list.Count);
            Assert.AreEqual(0, list[0]);
            Assert.AreEqual(2, list[1]);
        }

        public class multilineCases_one_values_with_alpha : IEnumerable
        {
            public IEnumerator GetEnumerator()
            {
                return new List<string> {
@"a
0",
@"0

c",
@"d

0"
,
@"0

e"
}.GetEnumerator();
            }
        }

        [Test]
        [TestCaseSource(typeof(multilineCases_one_values_with_alpha))]
        public void ParseEvenIntegersTests_multilineCases_one_values_with_alpha(string input)
        {
            var matches = new ParseEvenIntegers(input);
            var list = matches.ToList();
            Assert.AreEqual(1, list.Count);
            Assert.AreEqual(0, list[0]);
        }

        public class multilineCases_one_values_with_symbol : IEnumerable
        {
            public IEnumerator GetEnumerator()
            {
                return new List<string> {
@"#
0",
@"0

$",
@"&

0"
,
@"0

1/"
}.GetEnumerator();
            }
        }

        [Test]
        [TestCaseSource(typeof(multilineCases_one_values_with_symbol))]
        public void ParseEvenIntegersTests_multilineCases_one_values_with_symbol(string input)
        {
            var matches = new ParseEvenIntegers(input);
            var list = matches.ToList();
            Assert.AreEqual(1, list.Count);
            Assert.AreEqual(0, list[0]);
        }

        public class TestDataProvider : IEnumerable
        {
            public IEnumerator GetEnumerator()
            {
                return new List<int> { 2, 4, 6 }.GetEnumerator();
            }
        }

        public class multilineCases_one_values_with_even_second : IEnumerable
        {
            public IEnumerator GetEnumerator()
            {
                return new List<string> {
@" 1
 2 ",
@" 1
s
 2",
@"1
        -

 2",
   @" 2
 1 ",
@" 2
s
 1",
@"1
        -

 2"
}.GetEnumerator();
            }
        }

        [Test]
        [TestCaseSource(typeof(multilineCases_one_values_with_even_second))]
        public void ParseEvenIntegersTests_multilineCases_one_values_with_even_second(string input)
        {
            var matches = new ParseEvenIntegers(input);
            var list = matches.ToList();
            Assert.AreEqual(1, list.Count,"Count is wrong");
            Assert.AreEqual(2, list[0],"Value is wrong");
        }

        [Test]
        public void ParseEvenIntegersTests_multilineCases_100000()
        {
            for (var i = 0; i < 100000; i++)
            {
                var input = @"" + i.ToString() + @"

" + i.ToString() + @"

";
                var matches = new ParseEvenIntegers(input);
                var list = matches.ToList();
                foreach (var item in list)
                {
                    Assert.AreEqual(i, item);
                }
            }

        }

    }
}


text: __all__ = ["MainApp","MainContainer"]


text:
int print_slope(CL_sl_ld *to_print){
/*print slope*/
		CL_val *tmp;
		cout << "----------------------------------------------";
		cout << endl << "Vector: \"" << to_print->get_name() << "\":";
		cout << endl;
		tmp=to_print->get_values();
		while(tmp!=NULL){
			cout << " " << tmp->get_name();
			tmp=tmp->get_next();
		}
		return 1;
}

int cmd_print_slopes(CL_sl_ld **to_print, string parameters){
		CL_sl_ld *slopes;
		string tmp;
		stringstream ss_parameters;
		slopes=*to_print;
		ss_parameters.clear();
		ss_parameters.str(parameters);
		cout << endl << "Printing slope vectors:" << endl;
		if(slopes==NULL){
			cout << "WARNING: no slope vectors set in environment!";
			return 1;
		}
		if(parameters==""){ //all vectors
			while(slopes!=NULL){
				print_slope(slopes);
				slopes=slopes->get_next();
				if(slopes!=NULL) cout << endl;
			}
		}
		else{//specific cell(s)
			while(getline(ss_parameters, tmp, ' ')){
				while(slopes!=NULL){
					if(slopes->get_name()==tmp) {
						print_slope(slopes);
						break;
					}
					if(slopes->get_next()!=NULL) slopes=slopes->get_next();
				}
				slopes=*to_print;
			}
		}
		return 1;
}

int cmd_add_slope(string parameters, CL_sl_ld **slopes){
	stringstream ss_parameters;
	string tmp,name;
	CL_val *tmp_val,*aux_val;
	CL_sl_ld *tmp_slopes,*aux_slopes;
	ss_parameters.clear();
	ss_parameters.str(parameters);
	if(parameters=="") { //no name given
		cout << endl << "WARNING: Slope vector must have a name. Check help for usage.";
		return 1;
	}
	getline(ss_parameters, name, ' '); //get vector name
	cout << endl << "Adding vector \"" << name << "\"." << endl;
	aux_val=NULL;
	while(getline(ss_parameters, tmp, ' ')){ //check each value
		tmp_val = new CL_val(tmp);
		if(aux_val==NULL) aux_val = tmp_val;
		else aux_val->add_end(tmp_val);
		cout << " " << tmp;
	}
	if(aux_val==NULL){ //no values given
		cout << endl << "WARNING: Slope vector must have at least 1 value. Check help for usage";
		return 1;
	}
	//add the vector
	tmp_slopes= new CL_sl_ld(name, aux_val);
	if(*slopes==NULL) *slopes = tmp_slopes; //first cell?
	else{ //not first cell
		aux_slopes = *slopes;
		aux_slopes->add_end(tmp_slopes);
	}
	cout << endl << "Sucessfully added!";
	return 1;
}

int cmd_remove_slopes(CL_sl_ld **slopes, string parameters) {
/*Remove specified slope vectors.*/
//TO DO: verify why input cmd file cant remove multiple vectors
	CL_sl_ld *tmp_slope,*aux_slope;
	int flag_remove;
	stringstream ss_parameters;
	string tmp;
	ss_parameters.clear();
	ss_parameters.str(parameters);
	if(*slopes==NULL) {
		cout << "No slope vectors in the environment.";
		return 1;
	}
	cout << "Removing vectors: " << parameters << " from environment.";
	while(getline(ss_parameters, tmp, ' ')){ //check each parameter
		tmp_slope=*slopes;
		if(tmp_slope->get_name()==tmp){//found in first vector
			*slopes=tmp_slope->get_next();
			delete tmp_slope;
			cout << endl << "Successfully removed vector \"" << tmp << "\" from the environment.";
		}
		else{
			flag_remove=0;
			while(tmp_slope->get_next()!=NULL){ //check all cells
				if(tmp_slope->get_next()->get_name()==tmp){ //found cell
					flag_remove=1;
					aux_slope=tmp_slope->get_next();
					tmp_slope->set_next(aux_slope->get_next());
					delete aux_slope;
					cout << endl << "Successfully removed vector \"" << tmp << "\" from the environment.";
					break;
				}
			}
			if(!flag_remove) cout << endl << "Vector \"" << tmp << "\" not found!";
		}
	}
	return 1;
}

int print_load(CL_sl_ld *to_print){
/*print load*/
		CL_val *tmp;
		cout << "----------------------------------------------";
		cout << endl << "Vector: \"" << to_print->get_name() << "\":";
		cout << endl;
		tmp=to_print->get_values();
		while(tmp!=NULL){
			cout << " " << tmp->get_name();
			tmp=tmp->get_next();
		}
		return 1;
}

int cmd_print_loads(CL_sl_ld **to_print, string parameters){
		CL_sl_ld *loads;
		string tmp;
		stringstream ss_parameters;
		loads=*to_print;
		ss_parameters.clear();
		ss_parameters.str(parameters);
		cout << endl << "Printing load vectors:" << endl;
		if(loads==NULL){
			cout << "WARNING: no load vectors set in environment!";
			return 1;
		}
		if(parameters==""){ //all vectors
			while(loads!=NULL){
				print_load(loads);
				loads=loads->get_next();
				if(loads!=NULL) cout << endl;
			}
		}
		else{//specific cell(s)
			while(getline(ss_parameters, tmp, ' ')){
				while(loads!=NULL){
					if(loads->get_name()==tmp) {
						print_load(loads);
						break;
					}
					if(loads->get_next()!=NULL) loads=loads->get_next();
				}
				loads=*to_print;
			}
		}
		return 1;
}

int cmd_add_load(string parameters, CL_sl_ld **loads){
	stringstream ss_parameters;
	string tmp,name;
	CL_val *tmp_val,*aux_val;
	CL_sl_ld *tmp_loads,*aux_loads;
	ss_parameters.clear();
	ss_parameters.str(parameters);
	if(parameters=="") { //no name given
		cout << endl << "WARNING: Load vector must have a name. Check help for usage.";
		return 1;
	}
	getline(ss_parameters, name, ' '); //get vector name
	cout << endl << "Adding vector \"" << name << "\"." << endl;
	aux_val=NULL;
	while(getline(ss_parameters, tmp, ' ')){ //check each value
		tmp_val = new CL_val(tmp);
		if(aux_val==NULL) aux_val = tmp_val;
		else aux_val->add_end(tmp_val);
		cout << " " << tmp;
	}
	if(aux_val==NULL){ //no values given
		cout << endl << "WARNING: Load vector must have at least 1 value. Check help for usage";
		return 1;
	}
	//add the vector
	tmp_loads= new CL_sl_ld(name, aux_val);
	if(*loads==NULL) *loads = tmp_loads; //first cell?
	else{ //not first cell
		aux_loads = *loads;
		aux_loads->add_end(tmp_loads);
	}
	cout << endl << "Sucessfully added!";
	return 1;
}

int cmd_remove_loads(CL_sl_ld **loads, string parameters) {
/*Remove specified load vectors.*/
//TO DO: verify why input cmd file cant remove multiple vectors
	CL_sl_ld *tmp_load,*aux_load;
	int flag_remove;
	stringstream ss_parameters;
	string tmp;
	ss_parameters.clear();
	ss_parameters.str(parameters);
	if(*loads==NULL) {
		cout << "No load vectors in the environment.";
		return 1;
	}
	cout << "Removing vectors: " << parameters << " from environment.";
	while(getline(ss_parameters, tmp, ' ')){ //check each parameter
		tmp_load=*loads;
		if(tmp_load->get_name()==tmp){//found in first vector
			*loads=tmp_load->get_next();
			delete tmp_load;
			cout << endl << "Successfully removed vector \"" << tmp << "\" from the environment.";
		}
		else{
			flag_remove=0;
			while(tmp_load->get_next()!=NULL){ //check all vectors
				if(tmp_load->get_next()->get_name()==tmp){ //found vector
					flag_remove=1;
					aux_load=tmp_load->get_next();
					tmp_load->set_next(aux_load->get_next());
					delete aux_load;
					cout << endl << "Successfully removed vector \"" << tmp << "\" from the environment.";
					break;
				}
			}
			if(!flag_remove) cout << endl << "Vector \"" << tmp << "\" not found!";
		}
	}
	return 1;
}


text:
using System.Collections.Immutable;
using System.Composition;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
using Analyzer.Utilities;
using System.Threading;
using Analyzer.Utilities.Extensions;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.CodeActions;

namespace Microsoft.CodeQuality.Analyzers.ApiDesignGuidelines
{
    /// <summary>
    /// CA1066: Implement IEquatable when overriding Object.Equals
    /// CA1067: Override Object.Equals(object) when implementing IEquatable{T}
    /// </summary>
    [ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic), Shared]
    public sealed class EquatableFixer : CodeFixProvider
    {
        public override ImmutableArray<string> FixableDiagnosticIds { get; } =
            ImmutableArray.Create(EquatableAnalyzer.ImplementIEquatableRuleId, EquatableAnalyzer.OverrideObjectEqualsRuleId);

        public override FixAllProvider GetFixAllProvider()
        {
            // See https://github.com/dotnet/roslyn/blob/main/docs/analyzers/FixAllProvider.md for more information on Fix All Providers
            return WellKnownFixAllProviders.BatchFixer;
        }

        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxGenerator generator = SyntaxGenerator.GetGenerator(context.Document);
            SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            SyntaxNode declaration = root.FindNode(context.Span);
            declaration = generator.GetDeclaration(declaration);
            if (declaration == null)
            {
                return;
            }

            SemanticModel model =
                await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);
            if (model.GetDeclaredSymbol(declaration, context.CancellationToken) is not INamedTypeSymbol type || type.TypeKind != TypeKind.Class && type.TypeKind != TypeKind.Struct)
            {
                return;
            }

            INamedTypeSymbol? equatableType = model.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIEquatable1);
            if (equatableType == null)
            {
                return;
            }

            if (type.TypeKind == TypeKind.Struct && !TypeImplementsEquatable(type, equatableType))
            {
                string title = MicrosoftCodeQualityAnalyzersResources.ImplementEquatable;
                context.RegisterCodeFix(CodeAction.Create(
                    title,
                    async ct =>
                        await ImplementEquatableInStructAsync(context.Document, declaration, type, model.Compilation,
                            equatableType, ct).ConfigureAwait(false),
                    equivalenceKey: title), context.Diagnostics);
            }

            if (!type.OverridesEquals())
            {
                string title = MicrosoftCodeQualityAnalyzersResources.OverrideEqualsOnImplementingIEquatableCodeActionTitle;
                context.RegisterCodeFix(CodeAction.Create(
                    title,
                    async ct =>
                        await OverrideObjectEqualsAsync(context.Document, declaration, type, equatableType,
                            ct).ConfigureAwait(false),
                    equivalenceKey: title), context.Diagnostics);
            }
        }

        private static bool TypeImplementsEquatable(INamedTypeSymbol type, INamedTypeSymbol equatableType)
        {
            INamedTypeSymbol constructedEquatable = equatableType.Construct(type);
            INamedTypeSymbol implementation = type
                .Interfaces
                .FirstOrDefault(x => x.Equals(constructedEquatable));
            return implementation != null;
        }

        private static async Task<Document> ImplementEquatableInStructAsync(Document document, SyntaxNode declaration,
            INamedTypeSymbol typeSymbol, Compilation compilation, INamedTypeSymbol equatableType,
            CancellationToken cancellationToken)
        {
            var editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);
            var generator = editor.Generator;

            var equalsMethod = generator.MethodDeclaration(
                WellKnownMemberNames.ObjectEquals,
                new[]
                {
                    generator.ParameterDeclaration("other", generator.TypeExpression(typeSymbol))
                },
                returnType: generator.TypeExpression(SpecialType.System_Boolean),
                accessibility: Accessibility.Public,
                statements: generator.DefaultMethodBody(compilation));

            editor.AddMember(declaration, equalsMethod);

            INamedTypeSymbol constructedType = equatableType.Construct(typeSymbol);
            editor.AddInterfaceType(declaration, generator.TypeExpression(constructedType));

            return editor.GetChangedDocument();
        }

        private static async Task<Document> OverrideObjectEqualsAsync(Document document, SyntaxNode declaration,
            INamedTypeSymbol typeSymbol, INamedTypeSymbol equatableType, CancellationToken cancellationToken)
        {
            var editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);
            var generator = editor.Generator;

            var argumentName = generator.IdentifierName("obj");

            SyntaxNode returnStatement;

            if (HasExplicitEqualsImplementation(typeSymbol, equatableType))
            {
                returnStatement = typeSymbol.TypeKind == TypeKind.Class
                    ? GetReturnStatementForExplicitClass(generator, typeSymbol, argumentName, equatableType)
                    : GetReturnStatementForExplicitStruct(generator, typeSymbol, argumentName, equatableType);
            }
            else
            {
                returnStatement = typeSymbol.TypeKind == TypeKind.Class
                    ? GetReturnStatementForImplicitClass(generator, typeSymbol, argumentName)
                    : GetReturnStatementForImplicitStruct(generator, typeSymbol, argumentName);
            }

            var equalsMethod = generator.MethodDeclaration(
                WellKnownMemberNames.ObjectEquals,
                new[]
                {
                    generator.ParameterDeclaration(argumentName.ToString(),
                        generator.TypeExpression(SpecialType.System_Object))
                },
                returnType: generator.TypeExpression(SpecialType.System_Boolean),
                accessibility: Accessibility.Public,
                modifiers: DeclarationModifiers.Override,
                statements: new[] { returnStatement });

            editor.AddMember(declaration, equalsMethod);

            return editor.GetChangedDocument();
        }

        private static bool HasExplicitEqualsImplementation(INamedTypeSymbol typeSymbol, INamedTypeSymbol equatableType)
        {
            INamedTypeSymbol constructedType = equatableType.Construct(typeSymbol);
            IMethodSymbol constructedEqualsMethod = constructedType.GetMembers().OfType<IMethodSymbol>().FirstOrDefault();

            foreach (IMethodSymbol method in typeSymbol.GetMembers().OfType<IMethodSymbol>())
            {
                foreach (IMethodSymbol explicitImplementation in method.ExplicitInterfaceImplementations)
                {
                    if (explicitImplementation.Equals(constructedEqualsMethod))
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        private static SyntaxNode GetReturnStatementForExplicitClass(SyntaxGenerator generator,
            INamedTypeSymbol typeSymbol, SyntaxNode argumentName, INamedTypeSymbol equatableType)
        {
            return generator.ReturnStatement(
                generator.InvocationExpression(
                    generator.MemberAccessExpression(
                        generator.CastExpression(
                            equatableType.Construct(typeSymbol),
                            generator.ThisExpression()),
                        WellKnownMemberNames.ObjectEquals),
                    generator.TryCastExpression(
                        argumentName,
                        typeSymbol)));
        }

        private static SyntaxNode GetReturnStatementForExplicitStruct(SyntaxGenerator generator,
            INamedTypeSymbol typeSymbol, SyntaxNode argumentName, INamedTypeSymbol equatableType)
        {
            return generator.ReturnStatement(
                generator.LogicalAndExpression(
                    generator.IsTypeExpression(
                        argumentName,
                        typeSymbol),
                    generator.InvocationExpression(
                        generator.MemberAccessExpression(
                            generator.CastExpression(
                                equatableType.Construct(typeSymbol),
                                generator.ThisExpression()),
                            WellKnownMemberNames.ObjectEquals),
                        generator.CastExpression(
                            typeSymbol,
                            argumentName))));
        }

        private static SyntaxNode GetReturnStatementForImplicitClass(SyntaxGenerator generator,
            INamedTypeSymbol typeSymbol, SyntaxNode argumentName)
        {
            return generator.ReturnStatement(
                generator.InvocationExpression(
                    generator.IdentifierName(WellKnownMemberNames.ObjectEquals),
                    generator.Argument(
                        generator.TryCastExpression(
                            argumentName,
                            typeSymbol))));
        }

        private static SyntaxNode GetReturnStatementForImplicitStruct(SyntaxGenerator generator,
            INamedTypeSymbol typeSymbol, SyntaxNode argumentName)
        {
            return generator.ReturnStatement(
                generator.LogicalAndExpression(
                    generator.IsTypeExpression(
                        argumentName,
                        typeSymbol),
                    generator.InvocationExpression(
                        generator.IdentifierName(WellKnownMemberNames.ObjectEquals),
                        generator.CastExpression(
                            typeSymbol,
                            argumentName))));
        }
    }
}


text:
require 'spec_helper'

describe Role do
  context "Rollable" do
    it "should validate inclusion of roll names" do
      role = Role.new
      role.should_not be_valid
      role.user = User.create
      role.should_not be_valid
      role.rollable = Horse.create
      role.should_not be_valid
      role.name = User.role_names.first
      role.should be_valid
    end

    it "should validate inclusion of rollable types" do
      u = User.create
      r = u.roles.create(:name => "owner" )
      r.should be_valid
      r.rollable = u
      r.should_not be_valid
      r.rollable = Horse.create
      r.should be_valid
    end
  end
end


text:
package com.opengamma.analytics.financial.instrument.payment;

import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;

import org.testng.annotations.Test;
import org.threeten.bp.Period;
import org.threeten.bp.ZonedDateTime;

import com.opengamma.analytics.financial.instrument.index.IborIndex;
import com.opengamma.analytics.financial.instrument.index.IndexIborMaster;
import com.opengamma.analytics.financial.schedule.ScheduleCalculator;
import com.opengamma.financial.convention.calendar.Calendar;
import com.opengamma.financial.convention.calendar.MondayToFridayCalendar;
import com.opengamma.util.money.Currency;
import com.opengamma.util.test.TestGroup;
import com.opengamma.util.time.DateUtils;

/**
 * Test class for the coupon fixed accrued compounding.
 */
@Test(groups = TestGroup.UNIT)
public class CouponFixedAccruedCompoundingDefinitionTest {

  private static final Calendar NYC = new MondayToFridayCalendar("NYC");
  private static final IndexIborMaster MASTER_IBOR = IndexIborMaster.getInstance();
  private static final IborIndex USDLIBOR1M = MASTER_IBOR.getIndex("USDLIBOR1M");
  private static final Currency CURRENCY = USDLIBOR1M.getCurrency();

  private static final Period TENOR_3M = Period.ofMonths(3);
  private static final ZonedDateTime START_DATE = DateUtils.getUTCDate(2012, 8, 24);
  private static final double NOTIONAL = 123454321;
  private static final double FIXED_RATE = .02;

  private static final ZonedDateTime[] ACCRUAL_END_DATES = ScheduleCalculator.getAdjustedDateSchedule(START_DATE, TENOR_3M, true, false, USDLIBOR1M, NYC);
  private static final int NB_SUB_PERIOD = ACCRUAL_END_DATES.length;
  private static final ZonedDateTime[] ACCRUAL_START_DATES = new ZonedDateTime[NB_SUB_PERIOD];
  private static final double[] PAYMENT_ACCRUAL_FACTORS = new double[NB_SUB_PERIOD];
  private static final double PAYMENT_ACCRUAL_FACTOR;

  static {
    ACCRUAL_START_DATES[0] = START_DATE;
    for (int loopsub = 1; loopsub < NB_SUB_PERIOD; loopsub++) {
      ACCRUAL_START_DATES[loopsub] = ACCRUAL_END_DATES[loopsub - 1];
    }
    double af = 0.0;
    for (int loopsub = 0; loopsub < NB_SUB_PERIOD; loopsub++) {
      PAYMENT_ACCRUAL_FACTORS[loopsub] = USDLIBOR1M.getDayCount().getDayCountFraction(ACCRUAL_START_DATES[loopsub], ACCRUAL_END_DATES[loopsub]);
      af += PAYMENT_ACCRUAL_FACTORS[loopsub];
    }
    PAYMENT_ACCRUAL_FACTOR = af;
  }
  private static final ZonedDateTime[] FIXING_PERIOD_END_DATES = ScheduleCalculator.getAdjustedDate(ACCRUAL_START_DATES, USDLIBOR1M, NYC);
  private static final double[] FIXING_ACCRUAL_FACTORS = new double[NB_SUB_PERIOD];
  static {
    for (int loopsub = 0; loopsub < NB_SUB_PERIOD; loopsub++) {
      FIXING_ACCRUAL_FACTORS[loopsub] = USDLIBOR1M.getDayCount().getDayCountFraction(ACCRUAL_START_DATES[loopsub], FIXING_PERIOD_END_DATES[loopsub]);
    }
  }
  private static final ZonedDateTime PAYMENT_DATE = ACCRUAL_END_DATES[NB_SUB_PERIOD - 1];

  private static final CouponFixedAccruedCompoundingDefinition COUPON = CouponFixedAccruedCompoundingDefinition.from(CURRENCY, PAYMENT_DATE, ACCRUAL_START_DATES[0],
      ACCRUAL_END_DATES[NB_SUB_PERIOD - 1], PAYMENT_ACCRUAL_FACTOR, NOTIONAL, FIXED_RATE, NYC);

  @Test
  /**
   * Tests the getters.
   */
  public void testGetters() {
    assertEquals(COUPON.getPaymentDate(), PAYMENT_DATE);
    assertEquals(COUPON.getAccrualStartDate(), ACCRUAL_START_DATES[0]);
    assertEquals(COUPON.getAccrualEndDate(), ACCRUAL_END_DATES[NB_SUB_PERIOD - 1]);
    assertEquals(COUPON.getPaymentYearFraction(), PAYMENT_ACCRUAL_FACTOR, 1E-10);
    assertEquals(COUPON.getNotional(), NOTIONAL, 1E-2);
    assertEquals(COUPON.getRate(), FIXED_RATE, 1E-10);
    assertEquals(COUPON.getAmount(), NOTIONAL * Math.pow(1 + FIXED_RATE, PAYMENT_ACCRUAL_FACTOR));
    assertEquals(COUPON.getCalendar(), NYC);
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void nullCurrency() {
    CouponFixedAccruedCompoundingDefinition.from(null, PAYMENT_DATE, ACCRUAL_START_DATES[0],
        ACCRUAL_END_DATES[NB_SUB_PERIOD - 1], PAYMENT_ACCRUAL_FACTOR, NOTIONAL, FIXED_RATE, NYC);
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNullPaymentDate() {
    CouponFixedAccruedCompoundingDefinition.from(CURRENCY, null, ACCRUAL_START_DATES[0],
        ACCRUAL_END_DATES[NB_SUB_PERIOD - 1], PAYMENT_ACCRUAL_FACTOR, NOTIONAL, FIXED_RATE, NYC);
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testNegativePaymentAccrualFactor() {
    CouponFixedAccruedCompoundingDefinition.from(CURRENCY, PAYMENT_DATE, ACCRUAL_START_DATES[0],
        ACCRUAL_END_DATES[NB_SUB_PERIOD - 1], -PAYMENT_ACCRUAL_FACTOR, NOTIONAL, FIXED_RATE, NYC);
  }

  @Test
  /**
   * Tests the equal and hash code.
   */
  public void testEqualHash() {
    assertEquals("CouponIbor: equal-hash", COUPON, COUPON);
    final CouponFixedAccruedCompoundingDefinition other = CouponFixedAccruedCompoundingDefinition.from(CURRENCY, PAYMENT_DATE, ACCRUAL_START_DATES[0],
        ACCRUAL_END_DATES[NB_SUB_PERIOD - 1], PAYMENT_ACCRUAL_FACTOR, NOTIONAL, FIXED_RATE, NYC);
    assertEquals("CouponFixedCompoundingDefinition: equal-hash", other, COUPON);
    assertEquals("CouponFixedCompoundingDefinition: equal-hash", other.hashCode(), COUPON.hashCode());
    CouponFixedAccruedCompoundingDefinition modified;
    modified = CouponFixedAccruedCompoundingDefinition.from(CURRENCY, PAYMENT_DATE.plusDays(1), ACCRUAL_START_DATES[0],
        ACCRUAL_END_DATES[NB_SUB_PERIOD - 1], PAYMENT_ACCRUAL_FACTOR, NOTIONAL, FIXED_RATE, NYC);
    assertFalse("CouponIbor: equal-hash", COUPON.equals(modified));
    modified = CouponFixedAccruedCompoundingDefinition.from(CURRENCY, PAYMENT_DATE, ACCRUAL_START_DATES[0].plusDays(1),
        ACCRUAL_END_DATES[NB_SUB_PERIOD - 1], PAYMENT_ACCRUAL_FACTOR, NOTIONAL, FIXED_RATE, NYC);
    assertFalse("CouponIbor: equal-hash", COUPON.equals(modified));
    modified = CouponFixedAccruedCompoundingDefinition.from(CURRENCY, PAYMENT_DATE, ACCRUAL_START_DATES[0],
        ACCRUAL_END_DATES[NB_SUB_PERIOD - 1].plusDays(1), PAYMENT_ACCRUAL_FACTOR, NOTIONAL, FIXED_RATE, NYC);
    assertFalse("CouponIbor: equal-hash", COUPON.equals(modified));
    modified = CouponFixedAccruedCompoundingDefinition.from(CURRENCY, PAYMENT_DATE, ACCRUAL_START_DATES[0],
        ACCRUAL_END_DATES[NB_SUB_PERIOD - 1], PAYMENT_ACCRUAL_FACTOR + 1, NOTIONAL, FIXED_RATE, NYC);
    assertFalse("CouponIbor: equal-hash", COUPON.equals(modified));
    modified = CouponFixedAccruedCompoundingDefinition.from(CURRENCY, PAYMENT_DATE, ACCRUAL_START_DATES[0],
        ACCRUAL_END_DATES[NB_SUB_PERIOD - 1], PAYMENT_ACCRUAL_FACTOR, NOTIONAL + 1, FIXED_RATE, NYC);
    assertFalse("CouponIbor: equal-hash", COUPON.equals(modified));
    modified = CouponFixedAccruedCompoundingDefinition.from(CURRENCY, PAYMENT_DATE, ACCRUAL_START_DATES[0],
        ACCRUAL_END_DATES[NB_SUB_PERIOD - 1], PAYMENT_ACCRUAL_FACTOR, NOTIONAL, FIXED_RATE + 1, NYC);
    assertFalse("CouponIbor: equal-hash", COUPON.equals(modified));
  }

}


text:
  LOG(ERROR) << MSG_STR << " err=" << CURL_ERR << ":" \
             << curl_easy_strerror(CURL_ERR)
#define LOG_CURLFORM_ERR(CURL_ERR, MSG_STR) \
  LOG(ERROR) << MSG_STR << " err=" << CURL_ERR

namespace webmlive {

static const char* kExpectHeader = "Expect:";
static const char* kContentTypeHeader = "Content-Type: video/webm";
static const char* kFormName = "webm_file";
static const char* kWebmMimeType = "video/webm";
static const int kUnknownFileSize = -1;
static const int kBytesRequiredForResume = 32*1024;

class HttpUploaderImpl {
 public:
  typedef std::queue<std::string> UrlQueue;
  enum {
    // Libcurl reported an unexpected error.
    kLibCurlError = -401,
    kSuccess = 0,

    // Constant value used to stop libcurl when |StopRequested| returns true
    // in |WriteCallback|.
    kWriteCallbackStopRequest = 0,

    // Constant value used to stop libcurl when |StopRequested| returns true
    // in |ProgressCallback|.
    kProgressCallbackStopRequest = 1,

    // Returned by |Upload| when |WaitForUserData| was notified with an
    // unlocked |upload_buffer_|, which means |Stop| is waiting for
    // |UploadThread| to exit.
    kStopping = 2,
  };

  HttpUploaderImpl();
  ~HttpUploaderImpl();

  // Returns true when the uploader is ready to start an upload. Always returns
  // true when no uploads have been attempted.
  bool UploadComplete() const;

  // Copies user settings and configures libcurl.
  int Init(const HttpUploaderSettings& settings);

  // Locks |mutex_| and copies current stats to |ptr_stats|.
  int GetStats(HttpUploaderStats* ptr_stats);

  // Runs |UploadThread|, and starts waiting for user data.
  int Run();

  // Uploads user data.
  int UploadBuffer(const uint8* ptr_buffer, int32 length);

  // Stops the uploader.
  int Stop();

  // Adds |target_url| to |url_queue_|. Each time |UploadBuffer| is called, an
  // URL is popped off the queue and assigned to |target_url_|
  void EnqueueTargetUrl(const std::string& target_url);

 private:
  // Used by |UploadThread|. Returns true if user has called |Stop|.
  bool StopRequested();

  // Pass our callbacks, |ProgressCallback| and |WriteCallback|, to libcurl.
  CURLcode SetCurlCallbacks();

  // Pass user HTTP headers to libcurl, and disable HTTP 100 responses.
  CURLcode SetHeaders();

  // Configures libcurl to POST data buffers as file data in a form/multipart
  // HTTP POST.
  int SetupFormPost(const uint8* const ptr_buffer, int32 length);

  // Configures libcurl to POST data buffers as HTTP POST content-data.
  int SetupPost(const uint8* const ptr_buffer, int32 length);

  // Upload user data with libcurl.
  int Upload();

  // Wakes up |UploadThread| when users pass data through |UploadBuffer|.
  int WaitForUserData();

  // Libcurl progress callback function.  Acquires |mutex_| and updates
  // |stats_|.
  static int ProgressCallback(void* ptr_this,
                              double, double,  // we ignore download progress
                              double upload_total, double upload_current);

  // Logs HTTP response data received by libcurl.
  static size_t WriteCallback(char* buffer, size_t size, size_t nitems,
                              void* ptr_this);

  // Acquires |mutex_|, resets |stats_| and sets |start_ticks_|.
  void ResetStats();

  // Thread function. Wakes when |WaitForUserData| is notified by
  // |UploadBuffer|, and calls |Upload| to POST user data to the HTTP server
  // using libcurl.
  void UploadThread();

  // Stop flag. Internal callers use |StopRequested| to allow for
  // synchronization via |mutex_|.  Set by |Stop|, and responded to in
  // |UploadThread|.
  bool stop_;

  // Upload complete/ready to upload flag.  Initializes to true to allow
  // users of the uploader to base all Upload calls on |UploadComplete|.
  bool upload_complete_;

  // Condition variable used to wake |UploadThread| when a user code passes a
  // buffer to |UploadBuffer|.
  std::condition_variable buffer_ready_;

  // Mutex for synchronization of public method calls with |UploadThread|
  // activity. Mutable so |UploadComplete()| can be a const method.
  mutable std::mutex mutex_;

  // Thread object.
  std::shared_ptr<std::thread> upload_thread_;

  // Uploader start time.  Reset when via |ResetStatts| when |Init| is called.
  clock_t start_ticks_;

  // Libcurl pointer.
  CURL* ptr_curl_;

  // Libcurl form variable/data chain.
  curl_httppost* ptr_form_;

  // Pointer to end of libcurl form chain.
  curl_httppost* ptr_form_end_;

  // Pointer to list of user HTTP headers.
  curl_slist* ptr_headers_;

  // Uploader settings.
  HttpUploaderSettings settings_;

  // Basic stats stored by |ProgressCallback|.
  HttpUploaderStats stats_;

  // Simple buffer object that remains locked while libcurl uploads data in
  // |Upload|.  This second locking mechanism is in place to allow |mutex_| to
  // be unlocked while uploads are in progress (which prevents public methods
  // from blocking).
  LockableBuffer upload_buffer_;

  // The name of the file on the local system.  Note that it is not being read,
  // it's information included within the form data contained within the HTTP
  // post.
  std::string local_file_name_;

  WEBMLIVE_DISALLOW_COPY_AND_ASSIGN(HttpUploaderImpl);
};

///////////////////////////////////////////////////////////////////////////////
// HttpUploader
//

HttpUploader::HttpUploader() {
}

HttpUploader::~HttpUploader() {
}

// Return result of |UploadeComplete| on |ptr_uploader_|.
bool HttpUploader::UploadComplete() const {
  return ptr_uploader_->UploadComplete();
}

// Copy user settings, and setup the internal uploader object.
int HttpUploader::Init(const HttpUploaderSettings& settings) {
  ptr_uploader_.reset(new (std::nothrow) HttpUploaderImpl());  // NOLINT
  if (!ptr_uploader_) {
    LOG(ERROR) << "can't construct HttpUploaderImpl.";
    return kInitFailed;
  }
  int status = ptr_uploader_->Init(settings);
  if (status) {
    LOG(ERROR) << "uploader init failed. " << status;
    return kInitFailed;
  }
  return kSuccess;
}

// Return result of |GetStats| on |ptr_uploader_|.
int HttpUploader::GetStats(webmlive::HttpUploaderStats* ptr_stats) {
  return ptr_uploader_->GetStats(ptr_stats);
}

// Return result of |Run| on |ptr_uploader_|.
int HttpUploader::Run() {
  return ptr_uploader_->Run();
}

// Return result of |Stop| on |ptr_uploader_|.
int HttpUploader::Stop() {
  return ptr_uploader_->Stop();
}

// Return result of |UploadBuffer| on |ptr_uploader_|.
int HttpUploader::UploadBuffer(const uint8* ptr_buffer, int32 length) {
  return ptr_uploader_->UploadBuffer(ptr_buffer, length);
}

///////////////////////////////////////////////////////////////////////////////
// HttpUploaderImpl
//

HttpUploaderImpl::HttpUploaderImpl()
    : ptr_curl_(NULL),
      ptr_form_(NULL),
      ptr_form_end_(NULL),
      ptr_headers_(NULL),
      stop_(false),
      upload_complete_(true) {
}

HttpUploaderImpl::~HttpUploaderImpl() {
  if (ptr_curl_) {
    curl_easy_cleanup(ptr_curl_);
    ptr_curl_ = NULL;
  }
  if (ptr_form_) {
    curl_formfree(ptr_form_);
    ptr_form_ = NULL;
    ptr_form_end_ = NULL;
  }
  if (ptr_headers_) {
    curl_slist_free_all(ptr_headers_);
    ptr_headers_ = NULL;
  }
}

// Obtain lock on |mutex_| and return value of |upload_complete_|.
bool HttpUploaderImpl::UploadComplete() const {
  bool complete = false;
  std::unique_lock<std::mutex> lock(mutex_, std::try_to_lock);
  if (lock.owns_lock()) {
    complete = upload_complete_;
  }
  return complete;
}

// Initializes the upload:
// - copies user settings
// - sets basic libcurl settings (progress and write callbacks)
// - calls SetHeaders to pass user headers to libcurl
int HttpUploaderImpl::Init(const HttpUploaderSettings& settings) {
  if (settings.target_url.empty()) {
    LOG(ERROR) << "Empty target URL.";
    return HttpUploader::kUrlConfigError;
  }

  // copy user settings
  settings_ = settings;

  // Init libcurl.
  ptr_curl_ = curl_easy_init();
  if (!ptr_curl_) {
    LOG(ERROR) << "curl_easy_init failed!";
    return kLibCurlError;
  }

  // Enable progress reports from libcurl.
  CURLcode curl_ret = curl_easy_setopt(ptr_curl_, CURLOPT_NOPROGRESS, FALSE);
  if (curl_ret != CURLE_OK) {
    LOG_CURL_ERR(curl_ret, "curl progress enable failed.");
    return kLibCurlError;
  }

  // Set callbacks.
  curl_ret = SetCurlCallbacks();
  if (curl_ret != CURLE_OK) {
    LOG_CURL_ERR(curl_ret, "curl callback setup failed.");
    return kLibCurlError;
  }

  // Disable HTTP 100 responses, and set user HTTP headers.
  curl_ret = SetHeaders();
  if (curl_ret) {
    LOG_CURL_ERR(curl_ret, "unable to set headers.");
    return HttpUploader::kHeaderError;
  }

  local_file_name_ = settings_.local_file;
  ResetStats();
  return kSuccess;
}

// Obtain lock on |mutex_| and copy current stats values from |stats_| to
// |ptr_stats|.
int HttpUploaderImpl::GetStats(HttpUploaderStats* ptr_stats) {
  if (!ptr_stats) {
    LOG(ERROR) << "NULL ptr_stats";
    return HttpUploader::kInvalidArg;
  }
  std::lock_guard<std::mutex> lock(mutex_);
  ptr_stats->bytes_per_second = stats_.bytes_per_second;
  ptr_stats->bytes_sent_current = stats_.bytes_sent_current;
  ptr_stats->total_bytes_uploaded = stats_.total_bytes_uploaded;
  return kSuccess;
}

// Run |UploadThread| using |std::thread|.
int HttpUploaderImpl::Run() {
  assert(!upload_thread_);
  using std::bind;
  using std::shared_ptr;
  using std::thread;
  using std::nothrow;
  upload_thread_ = shared_ptr<thread>(
      new (nothrow) thread(bind(&HttpUploaderImpl::UploadThread,  // NOLINT
                                this)));
  return kSuccess;
}

// Try to obtain lock on |mutex_|, and upload the user buffer stored in
// |upload_buffer_| if the buffer is unlocked.  If the lock is obtained and the
// buffer is unlocked, |UploadBuffer| locks the buffer and notifies the upload
// thread through call to |notify_one| on the |buffer_ready_| condition
// variable.
int HttpUploaderImpl::UploadBuffer(const uint8* ptr_buf, int32 length) {
  int status = HttpUploader::kUploadInProgress;
  std::unique_lock<std::mutex> lock(mutex_, std::try_to_lock);
  if (lock.owns_lock() && !upload_buffer_.IsLocked()) {
    // Lock obtained; (re)initialize |upload_buffer_| with the user data...
    status = upload_buffer_.Init(ptr_buf, length);
    if (status) {
      LOG(ERROR) << "upload_buffer_ Init failed, status=" << status;
      return status;
    }

    // Lock |upload_buffer_|; it's unlocked by |UploadThread| once libcurl
    // finishes its run.
    status = upload_buffer_.Lock();
    if (status) {
      LOG(ERROR) << "upload_buffer_ Lock failed, status=" << status;
      return status;
    }
    upload_complete_ = false;

    // Wake |UploadThread|.
    LOG(INFO) << "waking uploader with " << length << " bytes";
    buffer_ready_.notify_one();
  }
  return status;
}

// Stops |UploadThread|. First it wakes the thread by calling |notify_one| on
// the |buffer_ready_| condition variable without locking |upload_buffer_|,
// which causes |Upload| to return |kStopping| to |UploadThread|, breaking the
// loop. This takes care of stopping if the uploader was waiting for user data
// in |WaitForUserData|.
// It then obtains lock on |mutex_|, sets |stop_| to true, and releases lock to
// ensure a running upload stops when |StopRequested| is called within the
// libcurl callbacks.
int HttpUploaderImpl::Stop() {
  assert(upload_thread_);
  if (UploadComplete()) {
    // Wake up the upload thread
    buffer_ready_.notify_one();
  }
  mutex_.lock();
  stop_ = true;
  mutex_.unlock();
  upload_thread_->join();
  return kSuccess;
}

// Try to obtain lock on |mutex_|, and return the value of |stop_| if lock is
// obtained.  Returns false if unable to obtain the lock.
bool HttpUploaderImpl::StopRequested() {
  bool stop_requested = false;
  std::unique_lock<std::mutex> lock(mutex_, std::try_to_lock);
  if (lock.owns_lock()) {
    stop_requested = stop_;
  }
  return stop_requested;
}

// Pass callback function pointers (|ProgressCallback| and |WriteCallback|),
// and data, |this|, to libcurl.
CURLcode HttpUploaderImpl::SetCurlCallbacks() {
  // set the progress callback function pointer
  CURLcode err = curl_easy_setopt(ptr_curl_, CURLOPT_PROGRESSFUNCTION,
                                  ProgressCallback);
  if (err != CURLE_OK) {
    LOG_CURL_ERR(err, "curl progress callback setup failed.");
    return err;
  }
  // set progress callback data pointer
  err = curl_easy_setopt(ptr_curl_, CURLOPT_PROGRESSDATA,
                         reinterpret_cast<void*>(this));
  if (err != CURLE_OK) {
    LOG_CURL_ERR(err, "curl progress callback data setup failed.");
    return err;
  }
  // set write callback function pointer
  err = curl_easy_setopt(ptr_curl_, CURLOPT_WRITEFUNCTION, WriteCallback);
  if (err != CURLE_OK) {
    LOG_CURL_ERR(err, "curl write callback setup failed.");
    return err;
  }
  // set write callback data pointer
  err = curl_easy_setopt(ptr_curl_, CURLOPT_WRITEDATA,
                         reinterpret_cast<void*>(this));
  if (err != CURLE_OK) {
    LOG_CURL_ERR(err, "curl write callback data setup failed.");
    return err;
  }
  return err;
}

// Disable HTTP 100 responses (send empty Expect header), and pass user HTTP
// headers into lib curl.
CURLcode HttpUploaderImpl::SetHeaders() {
  // Tell libcurl to omit "Expect: 100-continue" from requests
  ptr_headers_ = curl_slist_append(ptr_headers_, kExpectHeader);
  if (settings_.post_mode == webmlive::HTTP_POST) {
    // In form posts the video/webm mime-type is included in the form itself,
    // but in plain old HTTP posts the Content-Type must be video/webm.
    ptr_headers_ = curl_slist_append(ptr_headers_, kContentTypeHeader);
  }
  typedef std::map<std::string, std::string> StringMap;
  StringMap::const_iterator header_iter = settings_.headers.begin();
  // add user headers
  for (; header_iter != settings_.headers.end(); ++header_iter) {
    std::ostringstream header;
    header << header_iter->first.c_str() << ":" << header_iter->second.c_str();
    ptr_headers_ = curl_slist_append(ptr_headers_, header.str().c_str());
  }
  CURLcode err = curl_easy_setopt(ptr_curl_, CURLOPT_HTTPHEADER, ptr_headers_);
  if (err != CURLE_OK) {
    LOG_CURL_ERR(err, "setopt CURLOPT_HTTPHEADER failed err=");
  }
  return err;
}

// Sets necessary curl options for form based file upload, and adds the user
// form variables.
int HttpUploaderImpl::SetupFormPost(const uint8* const ptr_buffer,
                                    int32 length) {
  if (ptr_form_) {
    curl_formfree(ptr_form_);
    ptr_form_ = NULL;
    ptr_form_end_ = NULL;
  }
  typedef std::map<std::string, std::string> StringMap;
  StringMap::const_iterator var_iter = settings_.form_variables.begin();
  CURLFORMcode err;
  // add user form variables
  for (; var_iter != settings_.form_variables.end(); ++var_iter) {
    err = curl_formadd(&ptr_form_, &ptr_form_end_,
                       CURLFORM_COPYNAME, var_iter->first.c_str(),
                       CURLFORM_COPYCONTENTS, var_iter->second.c_str(),
                       CURLFORM_END);
    if (err != CURL_FORMADD_OK) {
      LOG_CURLFORM_ERR(err, "curl_formadd failed.");
      return HttpUploader::kFormError;
    }
  }
  // add buffer to form
  err = curl_formadd(&ptr_form_, &ptr_form_end_,
                     CURLFORM_COPYNAME, kFormName,
                     CURLFORM_BUFFER, local_file_name_.c_str(),
                     CURLFORM_BUFFERPTR, ptr_buffer,
                     CURLFORM_BUFFERLENGTH, length,
                     CURLFORM_CONTENTTYPE, kWebmMimeType,
                     CURLFORM_END);
  if (err != CURL_FORMADD_OK) {
    LOG_CURLFORM_ERR(err, "curl_formadd CURLFORM_FILE failed.");
    return err;
  }
  // pass the form to libcurl
  CURLcode err_setopt = curl_easy_setopt(ptr_curl_, CURLOPT_HTTPPOST,
                                         ptr_form_);
  if (err_setopt != CURLE_OK) {
    LOG_CURL_ERR(err_setopt, "setopt CURLOPT_HTTPPOST failed.");
    return err_setopt;
  }
  return kSuccess;
}

// Configures libcurl to POST data buffers as HTTP POST content-data.
int HttpUploaderImpl::SetupPost(const uint8* const ptr_buffer, int32 length) {
  CURLcode err_setopt = curl_easy_setopt(ptr_curl_, CURLOPT_POST, ptr_form_);
  if (err_setopt != CURLE_OK) {
    LOG_CURL_ERR(err_setopt, "setopt CURLOPT_HTTPPOST failed.");
    return err_setopt;
  }
  // Pass |ptr_buffer| to libcurl; it's used in the call to |curl_easy_perform|
  err_setopt = curl_easy_setopt(ptr_curl_, CURLOPT_POSTFIELDS, ptr_buffer);
  if (err_setopt != CURLE_OK) {
    LOG_CURL_ERR(err_setopt, "setopt CURLOPT_POSTFIELDS failed.");
    return err_setopt;
  }
  // Tell libcurl the size of |ptr_buffer|.  If libcurl is not informed of the
  // size before the call to |curl_easy_perform|, it will use strlen to
  // determine the length of the data.
  err_setopt = curl_easy_setopt(ptr_curl_, CURLOPT_POSTFIELDSIZE, length);
  if (err_setopt != CURLE_OK) {
    LOG_CURL_ERR(err_setopt, "setopt CURLOPT_POSTFIELDSIZE failed.");
    return err_setopt;
  }
  return kSuccess;
}

// Upload data using libcurl.
int HttpUploaderImpl::Upload() {
  if (!upload_buffer_.IsLocked()) {
    LOG(INFO) << "woke with unlocked buffer, stopping.";
    return kStopping;
  }

  uint8* ptr_data = NULL;
  int32 length = 0;
  int status = upload_buffer_.GetBuffer(&ptr_data, &length);
  if (status) {
    LOG(ERROR) << "error, could not get buffer pointer, status=" << status;
    return HttpUploader::kRunFailed;
  }

  LOG(INFO) << "upload buffer size=" << length;
  CURLcode err = curl_easy_setopt(ptr_curl_, CURLOPT_URL,
                                  settings_.target_url.c_str());
  if (err != CURLE_OK) {
    LOG_CURL_ERR(err, "could not pass URL to curl.");
    return HttpUploader::kUrlConfigError;
  }

  if (settings_.post_mode == webmlive::HTTP_FORM_POST) {
    if (SetupFormPost(ptr_data, length)) {
      LOG(ERROR) << "SetupFormPost failed!";
      return HttpUploader::kRunFailed;
    }
  } else {
    if (SetupPost(ptr_data, length)) {
      LOG(ERROR) << "SetupPost failed!";
      return HttpUploader::kRunFailed;
    }
  }

  err = curl_easy_perform(ptr_curl_);
  if (err != CURLE_OK) {
    LOG_CURL_ERR(err, "curl_easy_perform failed.");
  } else {
    int resp_code = 0;
    curl_easy_getinfo(ptr_curl_, CURLINFO_RESPONSE_CODE, &resp_code);
    LOG(INFO) << "server response code: " << resp_code;
  }

  // Update total bytes uploaded.
  double bytes_uploaded = 0;
  err = curl_easy_getinfo(ptr_curl_, CURLINFO_SIZE_UPLOAD, &bytes_uploaded);
  if (err != CURLE_OK) {
    LOG_CURL_ERR(err, "curl_easy_getinfo CURLINFO_SIZE_UPLOAD failed.");
  } else {
    std::lock_guard<std::mutex> lock(mutex_);
    stats_.bytes_sent_current = 0;
    stats_.total_bytes_uploaded += static_cast<int64>(bytes_uploaded);
  }

  return kSuccess;
}

// Idle the upload thread while awaiting user data.
int HttpUploaderImpl::WaitForUserData() {
  std::unique_lock<std::mutex> lock(mutex_);
  buffer_ready_.wait(lock);  // Unlock |mutex_| and idle the thread while we
                             // wait for the next chunk of user data.
  return kSuccess;
}

// Handle libcurl progress updates.
int HttpUploaderImpl::ProgressCallback(void* ptr_this,
                                       double download_total,
                                       double download_current,
                                       double upload_total,
                                       double upload_current) {
  // Ignore the download progress variables.
  download_total;
  download_current;
  HttpUploaderImpl* ptr_uploader_ =
    reinterpret_cast<HttpUploaderImpl*>(ptr_this);
  if (ptr_uploader_->StopRequested()) {
    LOG(ERROR) << "stop requested.";
    return kProgressCallbackStopRequest;
  }
  std::lock_guard<std::mutex> lock(ptr_uploader_->mutex_);
  HttpUploaderStats& stats = ptr_uploader_->stats_;
  stats.bytes_sent_current = static_cast<int64>(upload_current);
  double ticks_elapsed = clock() - ptr_uploader_->start_ticks_;
  double ticks_per_sec = CLOCKS_PER_SEC;
  stats.bytes_per_second =
      (upload_current + stats.total_bytes_uploaded) /
      (ticks_elapsed / ticks_per_sec);
  VLOG(4) << "total=" << static_cast<int>(upload_total) << " bytes_per_sec="
          << static_cast<int>(stats.bytes_per_second);
  return 0;
}

// Handle HTTP response data.
size_t HttpUploaderImpl::WriteCallback(char* buffer, size_t size,
                                       size_t nitems,
                                       void* ptr_this) {
  VLOG(4) << "size=" << size << " nitems=" << nitems;
  // TODO(tomfinegan): store response data for users
  std::string tmp;
  tmp.assign(buffer, size*nitems);
  LOG(INFO) << "from server:\n" << tmp.c_str();
  HttpUploaderImpl* ptr_uploader_ =
    reinterpret_cast<HttpUploaderImpl*>(ptr_this);
  if (ptr_uploader_->StopRequested()) {
    LOG(INFO) << "stop requested.";
    return kWriteCallbackStopRequest;
  }
  return size*nitems;
}

// Reset uploaded byte count, and store upload start time.
void HttpUploaderImpl::ResetStats() {
  std::lock_guard<std::mutex> lock(mutex_);
  stats_.bytes_per_second = 0;
  stats_.bytes_sent_current = 0;
  stats_.total_bytes_uploaded = 0;
  start_ticks_ = clock();
}

// Upload thread.  Wakes when user provides a buffer via call to
// |UploadBuffer|.
void HttpUploaderImpl::UploadThread() {
  LOG(INFO) << "upload thread running...";
  while (!StopRequested()) {
    LOG(INFO) << "upload thread waiting for buffer...";
    WaitForUserData();
    LOG(INFO) << "uploading buffer...";
    int status = Upload();
    if (status == kStopping) {
      break;
    }
    if (status) {
      LOG(ERROR) << "buffer upload failed, status=" << status;
      // TODO(tomfinegan): Report upload failure, and provide access to
      //                   response code and data.
    } else {
      std::lock_guard<std::mutex> lock(mutex_);
      LOG(INFO) << "unlocking upload buffer...";
      status = upload_buffer_.Unlock();
      if (status) {
        LOG(ERROR) << "unable to unlock buffer, status=" << status;
        // keep spinning, for now...
      }
      upload_complete_ = true;
    }
  }
  LOG(INFO) << "thread done";
}

}  // namespace webmlive


text:
/*
 * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT CHANGE IT!
 *
 * This file was generated using the Allogen bridge tool. If
 * you wish to make changes to it, you must edit the original
 * interface declaration file and regenerate the bridge code.
 */

#include "Allogen/Example/Bridge/Inheritance/SubClass2.hpp"

using namespace Allogen::CSharp;

namespace Allogen { namespace Example { namespace Inheritance {

    extern "C" ALLOGEN_EXPORT
    std::shared_ptr<Allogen::Example::Inheritance::SubClass2>* ALLOGEN_CALL
    Allogen_Example_Inheritance_SubClass2_Constructor() {
        return BridgedConstructor<Allogen::Example::Inheritance::SubClass2()>::call(
            []() {
                return new SubClass2();
            }
        );
    }

    extern "C" ALLOGEN_EXPORT
    void ALLOGEN_CALL
    Allogen_Example_Inheritance_SubClass2_Destructor(std::shared_ptr<Allogen::Example::Inheritance::SubClass2>* csthis) {
        BridgedMethod<Allogen::Example::Inheritance::SubClass2, void()>::call(
            csthis,
            [](Allogen::Example::Inheritance::SubClass2 *wself) {
                // delete wself;
            }
        );
    }

    extern "C" ALLOGEN_EXPORT
    void ALLOGEN_CALL
    Allogen_Example_Inheritance_SubClass2_doInSubclass2(std::shared_ptr<Allogen::Example::Inheritance::SubClass2>* csthis
    ) {
        return BridgedMethod<Allogen::Example::Inheritance::SubClass2, void()>::call(
            csthis,
            [](Allogen::Example::Inheritance::SubClass2 *wself) {
                return wself->doInSubclass2();
            }
        );

    }

    extern "C" ALLOGEN_EXPORT
    const char* ALLOGEN_CALL
    Allogen_Example_Inheritance_SubClass2_getName(std::shared_ptr<Allogen::Example::Inheritance::SubClass2>* csthis
    ) {
        return BridgedMethod<Allogen::Example::Inheritance::SubClass2, std::string()>::call(
            csthis,
            [](Allogen::Example::Inheritance::SubClass2 *wself) {
                return wself->getName();
            }
        );

    }

    extern "C" ALLOGEN_EXPORT
    void ALLOGEN_CALL
    Allogen_Example_Inheritance_SubClass2_fromNonvirtualBase(std::shared_ptr<Allogen::Example::Inheritance::SubClass2>* csthis
    ) {
        return BridgedMethod<Allogen::Example::Inheritance::SubClass2, void()>::call(
            csthis,
            [](Allogen::Example::Inheritance::SubClass2 *wself) {
                return wself->fromNonvirtualBase();
            }
        );

    }

}}}


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
Annls mycol. 18: 159 (1920)

#### Original name
Taphrina mexicana Syd.

### Remarks
null


text:
require 'resque-retry'

module ResqueBus
  class Rider
    extend Resque::Plugins::ExponentialBackoff

    class << self
      def perform(attributes = {})
        ResqueBus.note_deprecation "[MIGRATION] Note: new events will be using QueueBus::Rider"
        ::QueueBus::Rider.perform(attributes)
      end

      # @failure_hooks_already_ran on https://github.com/defunkt/resque/tree/1-x-stable
      # to prevent running twice
      def queue
        @my_queue
      end

      def on_failure_aaa(exception, *args)
        # note: sorted alphabetically
        # queue needs to be set for rety to work (know what queue in Requeue.class_to_queue)
        @my_queue = args[0]["bus_rider_queue"]
      end

      def on_failure_zzz(exception, *args)
        # note: sorted alphabetically
        @my_queue = nil
      end

    end
  end
end


text:
class AddDefaultToPlanVisibility < ActiveRecord::Migration
  def up
    change_column_default(:plans, :visibility, Plan.visibilities[:privately_visible])
  end
  def down
    change_column_default(:plans, :visibility, nil)
  end
end