text:
#include "test_utils.h"

#include "gtest/gtest.h"

#include <libcellml>

TEST(Component, construct)
{
    const std::string validName = "valid_name";

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName(validName);

    EXPECT_EQ("valid_name", v1->name());

    auto v2 = libcellml::Variable::create(validName);
    EXPECT_EQ("valid_name", v2->name());
}

TEST(Variable, setValidVariableName)
{
    const std::string in = "valid_name";
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component>\n"
        "    <variable name=\"valid_name\"/>\n"
        "  </component>\n"
        "</model>\n";
    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    libcellml::VariablePtr v = libcellml::Variable::create();
    v->setName(in);

    c->addVariable(v);
    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, setInvalidVariableName)
{
    const std::string in = "invalid name";
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component>\n"
        "    <variable name=\"invalid name\"/>\n"
        "  </component>\n"
        "</model>\n";
    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    libcellml::VariablePtr v = libcellml::Variable::create();
    v->setName(in);
    c->addVariable(v);
    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, validVariableName)
{
    const std::string in = "valid_name";
    const std::string e = in;
    libcellml::VariablePtr v = libcellml::Variable::create();
    v->setName(in);
    const std::string a = v->name();
    EXPECT_EQ(e, a);
}

TEST(Variable, invalidVariableName)
{
    const std::string in = "invalid name";
    const std::string e = in;
    libcellml::VariablePtr v = libcellml::Variable::create();
    v->setName(in);
    const std::string a = v->name();
    EXPECT_EQ(e, a);
}

TEST(Variable, setUnits)
{
    const std::string in = "dimensionless";
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component>\n"
        "    <variable units=\"dimensionless\"/>\n"
        "  </component>\n"
        "</model>\n";
    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    libcellml::VariablePtr v = libcellml::Variable::create();

    libcellml::UnitsPtr u = libcellml::Units::create();
    u->setName(in);
    v->setUnits(u);
    c->addVariable(v);
    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, setUnitsAndName)
{
    const std::string in = "valid_name";
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component>\n"
        "    <variable name=\"valid_name\" units=\"dimensionless\"/>\n"
        "  </component>\n"
        "</model>\n";
    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    libcellml::VariablePtr v = libcellml::Variable::create();
    v->setName(in);

    libcellml::UnitsPtr u = libcellml::Units::create();
    u->setName("dimensionless");
    v->setUnits(u);
    c->addVariable(v);

    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, removeUnits)
{
    const std::string in = "dimensionless";
    const std::string eVariableWithUnits =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component>\n"
        "    <variable units=\"dimensionless\"/>\n"
        "  </component>\n"
        "</model>\n";
    const std::string eVariableWithOutUnits =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component>\n"
        "    <variable/>\n"
        "  </component>\n"
        "</model>\n";
    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    libcellml::VariablePtr v = libcellml::Variable::create();

    libcellml::UnitsPtr u = libcellml::Units::create();
    u->setName(in);
    v->setUnits(u);
    c->addVariable(v);

    libcellml::PrinterPtr printer = libcellml::Printer::create();
    std::string a = printer->printModel(m);
    EXPECT_EQ(eVariableWithUnits, a);

    v->removeUnits();
    a = printer->printModel(m);
    EXPECT_EQ(eVariableWithOutUnits, a);
}

TEST(Variable, setInitialValueByString)
{
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component>\n"
        "    <variable initial_value=\"0.0\"/>\n"
        "  </component>\n"
        "</model>\n";
    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    libcellml::VariablePtr v = libcellml::Variable::create();
    v->setInitialValue("0.0");
    c->addVariable(v);
    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, setInitialValueByDouble)
{
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component>\n"
        "    <variable initial_value=\"0\"/>\n"
        "  </component>\n"
        "</model>\n";
    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    libcellml::VariablePtr v = libcellml::Variable::create();
    double value = 0.0;
    v->setInitialValue(value);
    c->addVariable(v);
    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, setInitialValueByReference)
{
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component>\n"
        "    <variable initial_value=\"referencedVariable\"/>\n"
        "  </component>\n"
        "</model>\n";
    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName("referencedVariable");
    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    libcellml::VariablePtr v2 = libcellml::Variable::create();
    v2->setInitialValue(v1);
    c->addVariable(v2);
    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, unsetInitialValue)
{
    libcellml::VariablePtr v = libcellml::Variable::create();
    v->setInitialValue("3.0");

    EXPECT_EQ(v->initialValue(), "3.0");

    v->removeInitialValue();
    EXPECT_EQ(v->initialValue(), "");
}

TEST(Variable, setInitialValue)
{
    libcellml::VariablePtr v = libcellml::Variable::create();
    const std::string e = "0.0";
    v->setInitialValue(e);
    const std::string a = v->initialValue();
    EXPECT_EQ(e, a);
}

TEST(Variable, setInterfaceTypeByInvalidString)
{
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component>\n"
        "    <variable interface=\"invalid\"/>\n"
        "  </component>\n"
        "</model>\n";
    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    libcellml::VariablePtr v = libcellml::Variable::create();
    v->setInterfaceType("invalid");
    c->addVariable(v);
    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, setInterfaceTypeNoneByValidString)
{
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component>\n"
        "    <variable interface=\"none\"/>\n"
        "  </component>\n"
        "</model>\n";
    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    libcellml::VariablePtr v = libcellml::Variable::create();
    v->setInterfaceType("none");
    c->addVariable(v);
    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, setInterfaceTypeNoneByEnum)
{
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component>\n"
        "    <variable interface=\"none\"/>\n"
        "  </component>\n"
        "</model>\n";
    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    libcellml::VariablePtr v = libcellml::Variable::create();
    v->setInterfaceType(libcellml::Variable::InterfaceType::NONE);
    c->addVariable(v);
    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, setInterfaceTypePrivate)
{
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component>\n"
        "    <variable interface=\"private\"/>\n"
        "  </component>\n"
        "</model>\n";
    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    libcellml::VariablePtr v = libcellml::Variable::create();
    v->setInterfaceType(libcellml::Variable::InterfaceType::PRIVATE);
    c->addVariable(v);
    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, setInterfaceTypePublic)
{
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component>\n"
        "    <variable interface=\"public\"/>\n"
        "  </component>\n"
        "</model>\n";
    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    libcellml::VariablePtr v = libcellml::Variable::create();
    v->setInterfaceType(libcellml::Variable::InterfaceType::PUBLIC);
    c->addVariable(v);
    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, setInterfaceTypePublicAndPrivate)
{
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component>\n"
        "    <variable interface=\"public_and_private\"/>\n"
        "  </component>\n"
        "</model>\n";
    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    libcellml::VariablePtr v = libcellml::Variable::create();
    v->setInterfaceType(libcellml::Variable::InterfaceType::PUBLIC_AND_PRIVATE);
    c->addVariable(v);
    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, removeInterfaceTypePublicAndPrivate)
{
    const std::string eWithInterfaceType =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component>\n"
        "    <variable interface=\"public_and_private\"/>\n"
        "  </component>\n"
        "</model>\n";
    const std::string eWithOutInterfaceType =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component>\n"
        "    <variable/>\n"
        "  </component>\n"
        "</model>\n";

    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    libcellml::VariablePtr v = libcellml::Variable::create();
    v->setInterfaceType(libcellml::Variable::InterfaceType::PUBLIC_AND_PRIVATE);
    c->addVariable(v);
    libcellml::PrinterPtr printer = libcellml::Printer::create();
    std::string a = printer->printModel(m);
    EXPECT_EQ(eWithInterfaceType, a);

    v->removeInterfaceType();

    a = printer->printModel(m);
    EXPECT_EQ(eWithOutInterfaceType, a);
}

TEST(Variable, setGetInterfaceType)
{
    libcellml::VariablePtr v1 = libcellml::Variable::create();
    libcellml::VariablePtr v2 = libcellml::Variable::create();
    libcellml::VariablePtr v3 = libcellml::Variable::create();
    libcellml::VariablePtr v4 = libcellml::Variable::create();
    libcellml::Variable::InterfaceType interfaceType1 = libcellml::Variable::InterfaceType::NONE;
    libcellml::Variable::InterfaceType interfaceType2 = libcellml::Variable::InterfaceType::PRIVATE;
    libcellml::Variable::InterfaceType interfaceType3 = libcellml::Variable::InterfaceType::PUBLIC;
    libcellml::Variable::InterfaceType interfaceType4 = libcellml::Variable::InterfaceType::PUBLIC_AND_PRIVATE;
    v1->setInterfaceType(interfaceType1);
    v2->setInterfaceType(interfaceType2);
    v3->setInterfaceType(interfaceType3);
    v4->setInterfaceType(interfaceType4);

    const std::string interfaceTypeString1 = "none";
    const std::string interfaceTypeString2 = "private";
    const std::string interfaceTypeString3 = "public";
    const std::string interfaceTypeString4 = "public_and_private";

    EXPECT_EQ(interfaceTypeString1, v1->interfaceType());
    EXPECT_EQ(interfaceTypeString2, v2->interfaceType());
    EXPECT_EQ(interfaceTypeString3, v3->interfaceType());
    EXPECT_EQ(interfaceTypeString4, v4->interfaceType());
}

TEST(Variable, hasInterfaceType)
{
    libcellml::VariablePtr v1 = libcellml::Variable::create();

    v1->setInterfaceType(libcellml::Variable::InterfaceType::PRIVATE);
    EXPECT_TRUE(v1->hasInterfaceType(libcellml::Variable::InterfaceType::PRIVATE));

    v1->setInterfaceType(libcellml::Variable::InterfaceType::PUBLIC);
    EXPECT_FALSE(v1->hasInterfaceType(libcellml::Variable::InterfaceType::PRIVATE));
    EXPECT_TRUE(v1->hasInterfaceType(libcellml::Variable::InterfaceType::PUBLIC));

    v1->setInterfaceType(libcellml::Variable::InterfaceType::NONE);
    EXPECT_FALSE(v1->hasInterfaceType(libcellml::Variable::InterfaceType::PUBLIC));
    EXPECT_TRUE(v1->hasInterfaceType(libcellml::Variable::InterfaceType::NONE));

    v1->setInterfaceType(libcellml::Variable::InterfaceType::PUBLIC_AND_PRIVATE);
    EXPECT_FALSE(v1->hasInterfaceType(libcellml::Variable::InterfaceType::NONE));
    EXPECT_TRUE(v1->hasInterfaceType(libcellml::Variable::InterfaceType::PUBLIC_AND_PRIVATE));

    v1->removeInterfaceType();
    EXPECT_FALSE(v1->hasInterfaceType(libcellml::Variable::InterfaceType::PUBLIC_AND_PRIVATE));
    EXPECT_TRUE(v1->hasInterfaceType(libcellml::Variable::InterfaceType::NONE));
}

TEST(Variable, addVariable)
{
    const std::string in = "valid_name";
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component name=\"valid_name\">\n"
        "    <variable name=\"valid_name\" units=\"dimensionless\"/>\n"
        "  </component>\n"
        "</model>\n";

    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    c->setName(in);

    libcellml::VariablePtr v = libcellml::Variable::create();
    v->setName(in);
    c->addVariable(v);

    libcellml::UnitsPtr u = libcellml::Units::create();
    u->setName("dimensionless");
    v->setUnits(u);

    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, parentOfVariable)
{
    libcellml::ComponentPtr c = libcellml::Component::create();
    libcellml::VariablePtr v = libcellml::Variable::create();
    c->addVariable(v);
    EXPECT_EQ(c, v->parent());
}

TEST(Variable, nullParentOfVariable)
{
    libcellml::VariablePtr v = libcellml::Variable::create();
    EXPECT_EQ(nullptr, v->parent());
}

TEST(Variable, hasEquivalentVariable)
{
    libcellml::VariablePtr v1 = libcellml::Variable::create();
    libcellml::VariablePtr v2 = libcellml::Variable::create();
    libcellml::VariablePtr v3 = libcellml::Variable::create();

    EXPECT_FALSE(v1->hasEquivalentVariable(v1));
    EXPECT_FALSE(v1->hasEquivalentVariable(v2));
    EXPECT_FALSE(v1->hasEquivalentVariable(v3));

    EXPECT_FALSE(v2->hasEquivalentVariable(v1));
    EXPECT_FALSE(v2->hasEquivalentVariable(v2));
    EXPECT_FALSE(v2->hasEquivalentVariable(v3));

    EXPECT_FALSE(v3->hasEquivalentVariable(v1));
    EXPECT_FALSE(v3->hasEquivalentVariable(v2));
    EXPECT_FALSE(v3->hasEquivalentVariable(v3));

    libcellml::Variable::addEquivalence(v1, v2);
    libcellml::Variable::addEquivalence(v2, v3);

    EXPECT_FALSE(v1->hasEquivalentVariable(v1));
    EXPECT_TRUE(v1->hasEquivalentVariable(v2));
    EXPECT_FALSE(v1->hasEquivalentVariable(v3));

    EXPECT_TRUE(v2->hasEquivalentVariable(v1));
    EXPECT_FALSE(v2->hasEquivalentVariable(v2));
    EXPECT_TRUE(v2->hasEquivalentVariable(v3));

    EXPECT_FALSE(v3->hasEquivalentVariable(v1));
    EXPECT_TRUE(v3->hasEquivalentVariable(v2));
    EXPECT_FALSE(v3->hasEquivalentVariable(v3));
}

TEST(Variable, hasIndirectEquivalentVariable)
{
    libcellml::VariablePtr v1 = libcellml::Variable::create();
    libcellml::VariablePtr v2 = libcellml::Variable::create();
    libcellml::VariablePtr v3 = libcellml::Variable::create();

    EXPECT_FALSE(v1->hasEquivalentVariable(v1, true));
    EXPECT_FALSE(v1->hasEquivalentVariable(v2, true));
    EXPECT_FALSE(v1->hasEquivalentVariable(v3, true));

    EXPECT_FALSE(v2->hasEquivalentVariable(v1, true));
    EXPECT_FALSE(v2->hasEquivalentVariable(v2, true));
    EXPECT_FALSE(v2->hasEquivalentVariable(v3, true));

    EXPECT_FALSE(v3->hasEquivalentVariable(v1, true));
    EXPECT_FALSE(v3->hasEquivalentVariable(v2, true));
    EXPECT_FALSE(v3->hasEquivalentVariable(v3, true));

    libcellml::Variable::addEquivalence(v1, v2);
    libcellml::Variable::addEquivalence(v2, v3);

    EXPECT_FALSE(v1->hasEquivalentVariable(v1, true));
    EXPECT_TRUE(v1->hasEquivalentVariable(v2, true));
    EXPECT_TRUE(v1->hasEquivalentVariable(v3, true));

    EXPECT_TRUE(v2->hasEquivalentVariable(v1, true));
    EXPECT_FALSE(v2->hasEquivalentVariable(v2, true));
    EXPECT_TRUE(v2->hasEquivalentVariable(v3, true));

    EXPECT_TRUE(v3->hasEquivalentVariable(v1, true));
    EXPECT_TRUE(v3->hasEquivalentVariable(v2, true));
    EXPECT_FALSE(v3->hasEquivalentVariable(v3, true));
}

TEST(Variable, addVariableToUnnamedComponent)
{
    const std::string in = "valid_name";
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component>\n"
        "    <variable name=\"valid_name\"/>\n"
        "  </component>\n"
        "</model>\n";

    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    libcellml::VariablePtr v = libcellml::Variable::create();

    v->setName(in);
    c->addVariable(v);

    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, addTwoVariables)
{
    const std::string in = "valid_name";
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component name=\"valid_name\">\n"
        "    <variable name=\"variable1\"/>\n"
        "    <variable name=\"variable2\"/>\n"
        "  </component>\n"
        "</model>\n";

    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    c->setName(in);

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName("variable1");
    c->addVariable(v1);

    libcellml::VariablePtr v2 = libcellml::Variable::create();
    v2->setName("variable2");
    c->addVariable(v2);

    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, addVariablesWithAndWithoutNameAndUnits)
{
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component>\n"
        "    <variable name=\"var1\" units=\"dimensionless\"/>\n"
        "    <variable name=\"var2\"/>\n"
        "    <variable units=\"dimensionless\"/>\n"
        "    <variable/>\n"
        "  </component>\n"
        "</model>\n";

    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName("var1");
    libcellml::VariablePtr v2 = libcellml::Variable::create();
    v2->setName("var2");
    libcellml::VariablePtr v3 = libcellml::Variable::create();
    libcellml::VariablePtr v4 = libcellml::Variable::create();

    c->addVariable(v1);
    c->addVariable(v2);
    c->addVariable(v3);
    c->addVariable(v4);

    libcellml::UnitsPtr u = libcellml::Units::create();
    u->setName("dimensionless");
    v1->setUnits(u);
    v3->setUnits(u);

    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, componentWithTwoVariablesWithInitialValues)
{
    const std::string in = "valid_name";
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component name=\"valid_name\">\n"
        "    <variable initial_value=\"1\"/>\n"
        "    <variable initial_value=\"-1\"/>\n"
        "  </component>\n"
        "</model>\n";

    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    c->setName(in);

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setInitialValue(1.0);
    c->addVariable(v1);

    libcellml::VariablePtr v2 = libcellml::Variable::create();
    v2->setInitialValue(-1.0);
    c->addVariable(v2);

    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, removeVariableMethods)
{
    const std::string in = "valid_name";
    const std::string e1 =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component name=\"valid_name\">\n"
        "    <variable name=\"variable2\"/>\n"
        "  </component>\n"
        "</model>\n";
    const std::string e2 =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component name=\"valid_name\"/>\n"
        "</model>\n";

    libcellml::ModelPtr m = createModelWithComponent();
    libcellml::ComponentPtr c = m->component(0);
    libcellml::VariablePtr v1 = libcellml::Variable::create();
    libcellml::VariablePtr v2 = libcellml::Variable::create();
    libcellml::VariablePtr v3 = libcellml::Variable::create();
    libcellml::VariablePtr v4 = libcellml::Variable::create();
    libcellml::VariablePtr v5 = libcellml::Variable::create();

    c->setName(in);
    v1->setName("variable1");
    v2->setName("variable2");
    v3->setName("variable3");
    v4->setName("variable4");

    c->addVariable(v1);
    c->addVariable(v2);
    c->addVariable(v3);

    EXPECT_TRUE(c->removeVariable("variable1"));
    EXPECT_TRUE(c->removeVariable(v3));
    libcellml::PrinterPtr printer = libcellml::Printer::create();
    std::string a = printer->printModel(m);
    EXPECT_EQ(e1, a);
    EXPECT_FALSE(c->removeVariable("BAD_NAME"));

    c->addVariable(v4);
    c->removeAllVariables();
    a = printer->printModel(m);
    EXPECT_EQ(e2, a);
    EXPECT_FALSE(c->removeVariable(v5));

    c->addVariable(v1);
    c->addVariable(v2);
    c->addVariable(v3);

    EXPECT_TRUE(c->removeVariable(0)); // v1
    EXPECT_TRUE(c->removeVariable(1)); // new index of v3
    a = printer->printModel(m);
    EXPECT_EQ(e1, a);
    EXPECT_FALSE(c->removeVariable(1));
}

TEST(Variable, variableMethods)
{
    const std::string in = "valid_name";
    libcellml::ComponentPtr c = libcellml::Component::create();
    c->setName(in);

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName("variable1");
    c->addVariable(v1);
    libcellml::VariablePtr v2 = libcellml::Variable::create();
    v2->setName("variable2");
    c->addVariable(v2);
    libcellml::VariablePtr v3 = libcellml::Variable::create();
    v3->setName("variable3");
    c->addVariable(v3);
    libcellml::VariablePtr v4 = libcellml::Variable::create();
    v4->setName("variable4");
    c->addVariable(v4);

    // Get by string
    libcellml::VariablePtr vMethod1 = c->variable("variable1");
    const std::string a1 = vMethod1->name();
    EXPECT_EQ("variable1", a1);

    // Get by index
    libcellml::VariablePtr vMethod2 = c->variable(1);
    const std::string a2 = vMethod2->name();
    EXPECT_EQ("variable2", a2);

    // Get const by string
    const libcellml::VariablePtr vMethod3 = c->variable("variable3");
    const std::string a3 = vMethod3->name();
    EXPECT_EQ("variable3", a3);

    // Get const by index
    const libcellml::VariablePtr vMethod4 = c->variable(3);
    const std::string a4 = vMethod4->name();
    EXPECT_EQ("variable4", a4);

    // Get invalid index
    EXPECT_EQ(nullptr, c->variable(7));

    // Get non-existent variable by string
    EXPECT_EQ(nullptr, c->variable("doesntexist"));
}

TEST(Variable, takeVariableMethods)
{
    const std::string in = "valid_name";
    libcellml::ComponentPtr c = libcellml::Component::create();
    c->setName(in);

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName("variable1");
    c->addVariable(v1);
    libcellml::VariablePtr v2 = libcellml::Variable::create();
    v2->setName("variable2");
    c->addVariable(v2);
    libcellml::VariablePtr v3 = libcellml::Variable::create();
    v3->setName("variable3");
    c->addVariable(v3);
    libcellml::VariablePtr v4 = libcellml::Variable::create();
    v4->setName("variable4");
    c->addVariable(v4);

    // Take by index
    libcellml::VariablePtr tv = c->takeVariable(0);
    std::string tvn = tv->name();
    EXPECT_EQ("variable1", tvn);
    libcellml::VariablePtr gv = c->variable(0);
    std::string gvn = gv->name();
    EXPECT_EQ("variable2", gvn);
    tv = c->takeVariable(0);
    tvn = tv->name();
    EXPECT_EQ("variable2", tvn);
    gv = c->variable(0);
    gvn = gv->name();
    EXPECT_EQ("variable3", gvn);

    // Take by string
    libcellml::VariablePtr tv3 = c->takeVariable("variable3");
    const std::string tvn3 = tv3->name();
    EXPECT_EQ("variable3", tvn3);

    // Get invalid index
    EXPECT_EQ(nullptr, c->takeVariable(737));

    // Get non-existent variable by string
    EXPECT_EQ(nullptr, c->takeVariable("notreal"));
    EXPECT_EQ(nullptr, c->takeVariable("doesntexist"));
}

TEST(Variable, modelWithComponentWithVariableWithValidName)
{
    const std::string in = "valid_name";
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component name=\"valid_name\">\n"
        "    <variable name=\"valid_name\" units=\"dimensionless\"/>\n"
        "  </component>\n"
        "</model>\n";

    libcellml::ModelPtr m = libcellml::Model::create();

    libcellml::ComponentPtr c = libcellml::Component::create();
    c->setName(in);
    m->addComponent(c);

    libcellml::VariablePtr v = libcellml::Variable::create();
    v->setName(in);
    c->addVariable(v);

    libcellml::UnitsPtr u = libcellml::Units::create();
    u->setName("dimensionless");
    v->setUnits(u);

    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
    EXPECT_EQ("valid_name", v->name());
}

TEST(Variable, modelWithComponentWithVariableWithInvalidName)
{
    const std::string in = "invalid name";
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component name=\"invalid name\">\n"
        "    <variable name=\"invalid name\" units=\"dimensionless\"/>\n"
        "  </component>\n"
        "</model>\n";

    libcellml::ModelPtr m = libcellml::Model::create();

    libcellml::ComponentPtr c = libcellml::Component::create();
    c->setName(in);
    m->addComponent(c);

    libcellml::VariablePtr v = libcellml::Variable::create();
    v->setName(in);
    c->addVariable(v);

    libcellml::UnitsPtr u = libcellml::Units::create();
    u->setName("dimensionless");
    v->setUnits(u);

    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
    EXPECT_EQ("invalid name", v->name());
}

TEST(Variable, modelWithComponentWithVariableWithInvalidUnitsNameAndParse)
{
    const std::string in = "valid_name";
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component name=\"valid_name\">\n"
        "    <variable name=\"valid_name\" units=\"invalid name\"/>\n"
        "  </component>\n"
        "</model>\n";

    libcellml::ModelPtr m = libcellml::Model::create();

    libcellml::ComponentPtr c = libcellml::Component::create();
    c->setName(in);
    m->addComponent(c);

    libcellml::VariablePtr v = libcellml::Variable::create();
    v->setName(in);
    c->addVariable(v);

    libcellml::UnitsPtr u = libcellml::Units::create();
    u->setName("invalid name");
    v->setUnits(u);

    libcellml::PrinterPtr printer = libcellml::Printer::create();
    std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
    EXPECT_EQ("invalid name", u->name());

    // Parse
    libcellml::ParserPtr parser = libcellml::Parser::create();
    libcellml::ModelPtr model = parser->parseModel(e);
    a = printer->printModel(model);
    EXPECT_EQ(e, a);
}

TEST(Variable, modelWithComponentWithTwoNamedVariablesWithInitialValues)
{
    const std::string in = "valid_name";
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component name=\"valid_name\">\n"
        "    <variable name=\"variable1\" initial_value=\"1.0\"/>\n"
        "    <variable name=\"variable2\" initial_value=\"-1.0\"/>\n"
        "  </component>\n"
        "</model>\n";

    libcellml::ModelPtr m = libcellml::Model::create();

    libcellml::ComponentPtr c = libcellml::Component::create();
    c->setName(in);
    m->addComponent(c);

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName("variable1");
    v1->setInitialValue("1.0");
    c->addVariable(v1);

    libcellml::VariablePtr v2 = libcellml::Variable::create();
    v2->setName("variable2");
    v2->setInitialValue("-1.0");
    c->addVariable(v2);

    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, modelWithComponentWithTwoNamedVariablesWithInitialValuesOneReferenced)
{
    const std::string in = "valid_name";
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component name=\"valid_name\">\n"
        "    <variable name=\"variable1\" initial_value=\"1\"/>\n"
        "    <variable name=\"variable2\" initial_value=\"variable1\"/>\n"
        "  </component>\n"
        "</model>\n";

    libcellml::ModelPtr m = libcellml::Model::create();

    libcellml::ComponentPtr c = libcellml::Component::create();
    c->setName(in);
    m->addComponent(c);

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName("variable1");
    v1->setInitialValue(1.0);
    c->addVariable(v1);

    libcellml::VariablePtr v2 = libcellml::Variable::create();
    v2->setName("variable2");
    v2->setInitialValue(v1);
    c->addVariable(v2);

    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, modelWithComponentWithTwoNamedVariablesWithInitialValuesAndParse)
{
    const std::string in = "valid_name";
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component name=\"valid_name\">\n"
        "    <variable name=\"variable1\" initial_value=\"1.0\"/>\n"
        "    <variable name=\"variable2\" initial_value=\"-1.0\"/>\n"
        "  </component>\n"
        "</model>\n";

    libcellml::ModelPtr m = libcellml::Model::create();

    libcellml::ComponentPtr c = libcellml::Component::create();
    c->setName(in);
    m->addComponent(c);

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName("variable1");
    v1->setInitialValue("1.0");
    c->addVariable(v1);

    libcellml::VariablePtr v2 = libcellml::Variable::create();
    v2->setName("variable2");
    v2->setInitialValue("-1.0");
    c->addVariable(v2);

    libcellml::ParserPtr parser = libcellml::Parser::create();
    libcellml::ModelPtr model = parser->parseModel(e);
    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(model);
    EXPECT_EQ(e, a);
}

TEST(Variable, modelWithComponentWithFourNamedVariablesWithInterfaces)
{
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component name=\"valid_name\">\n"
        "    <variable name=\"variable1\" interface=\"none\"/>\n"
        "    <variable name=\"variable2\" interface=\"public\"/>\n"
        "    <variable name=\"variable3\" interface=\"private\"/>\n"
        "    <variable name=\"variable4\" interface=\"public_and_private\"/>\n"
        "  </component>\n"
        "</model>\n";

    libcellml::ModelPtr m = libcellml::Model::create();

    libcellml::ComponentPtr c = libcellml::Component::create();
    c->setName("valid_name");
    m->addComponent(c);

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName("variable1");
    v1->setInterfaceType(libcellml::Variable::InterfaceType::NONE);
    c->addVariable(v1);

    libcellml::VariablePtr v2 = libcellml::Variable::create();
    v2->setName("variable2");
    v2->setInterfaceType(libcellml::Variable::InterfaceType::PUBLIC);
    c->addVariable(v2);

    libcellml::VariablePtr v3 = libcellml::Variable::create();
    v3->setName("variable3");
    v3->setInterfaceType(libcellml::Variable::InterfaceType::PRIVATE);
    c->addVariable(v3);

    libcellml::VariablePtr v4 = libcellml::Variable::create();
    v4->setName("variable4");
    v4->setInterfaceType(libcellml::Variable::InterfaceType::PUBLIC_AND_PRIVATE);
    c->addVariable(v4);

    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(m);
    EXPECT_EQ(e, a);
}

TEST(Variable, modelWithComponentWithFourNamedVariablesWithInterfacesAndParse)
{
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component name=\"valid_name\">\n"
        "    <variable name=\"variable1\" interface=\"none\"/>\n"
        "    <variable name=\"variable2\" interface=\"public\"/>\n"
        "    <variable name=\"variable3\" interface=\"private\"/>\n"
        "    <variable name=\"variable4\" interface=\"public_and_private\"/>\n"
        "  </component>\n"
        "</model>\n";

    libcellml::ModelPtr m = libcellml::Model::create();

    libcellml::ComponentPtr c = libcellml::Component::create();
    c->setName("valid_name");
    m->addComponent(c);

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName("variable1");
    v1->setInterfaceType(libcellml::Variable::InterfaceType::NONE);
    c->addVariable(v1);

    libcellml::VariablePtr v2 = libcellml::Variable::create();
    v2->setName("variable2");
    v2->setInterfaceType("public");
    c->addVariable(v2);

    libcellml::VariablePtr v3 = libcellml::Variable::create();
    v3->setName("variable3");
    v3->setInterfaceType(libcellml::Variable::InterfaceType::PRIVATE);
    c->addVariable(v3);

    libcellml::VariablePtr v4 = libcellml::Variable::create();
    v4->setName("variable4");
    v4->setInterfaceType(libcellml::Variable::InterfaceType::PUBLIC_AND_PRIVATE);
    c->addVariable(v4);

    libcellml::ParserPtr parser = libcellml::Parser::create();
    libcellml::ModelPtr model = parser->parseModel(e);
    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(model);
    EXPECT_EQ(e, a);
}

TEST(Variable, modelWithComponentWithFiveNamedVariablesWithInterfacesAndParse)
{
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component name=\"valid_name\">\n"
        "    <variable name=\"variable1\" interface=\"none\"/>\n"
        "    <variable name=\"variable2\" interface=\"public\"/>\n"
        "    <variable name=\"variable3\" interface=\"private\"/>\n"
        "    <variable name=\"variable4\" interface=\"public_and_private\"/>\n"
        "    <variable name=\"variable5\"/>\n"
        "  </component>\n"
        "</model>\n";

    libcellml::ModelPtr m = libcellml::Model::create();

    libcellml::ComponentPtr c = libcellml::Component::create();
    c->setName("valid_name");
    m->addComponent(c);

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName("variable1");
    v1->setInterfaceType(libcellml::Variable::InterfaceType::NONE);
    c->addVariable(v1);

    libcellml::VariablePtr v2 = libcellml::Variable::create();
    v2->setName("variable2");
    v2->setInterfaceType("public");
    c->addVariable(v2);

    libcellml::VariablePtr v3 = libcellml::Variable::create();
    v3->setName("variable3");
    v3->setInterfaceType(libcellml::Variable::InterfaceType::PRIVATE);
    c->addVariable(v3);

    libcellml::VariablePtr v4 = libcellml::Variable::create();
    v4->setName("variable4");
    v4->setInterfaceType(libcellml::Variable::InterfaceType::PUBLIC_AND_PRIVATE);
    c->addVariable(v4);

    libcellml::VariablePtr v5 = libcellml::Variable::create();
    v5->setName("variable4");
    v5->setInterfaceType("other");
    c->addVariable(v5);

    libcellml::ParserPtr parser = libcellml::Parser::create();
    libcellml::ModelPtr model = parser->parseModel(e);
    libcellml::PrinterPtr printer = libcellml::Printer::create();
    const std::string a = printer->printModel(model);
    EXPECT_EQ(e, a);
}

TEST(Variable, modelUnitsAttributeBeforeNameAttribute)
{
    const std::string e =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<model xmlns=\"http://www.cellml.org/cellml/2.0#\">\n"
        "  <component name=\"valid_name\">\n"
        "    <variable units=\"dimensionless\" name=\"variable1\" interface=\"none\"/>\n"
        "    <variable id=\"sin\" units=\"dimensionless\" name=\"sin1\" interface=\"public_and_private\"/>\n"
        "    <variable id=\"deriv_approx_initial_value\" units=\"dimensionless\" initial_value=\"0\" name=\"deriv_approx_initial_value\" interface=\"public_and_private\"/>\n"
        "  </component>\n"
        "</model>\n";

    libcellml::ParserPtr parser = libcellml::Parser::create();
    parser->parseModel(e);
    EXPECT_EQ(size_t(0), parser->issueCount());
}

TEST(Variable, parentlessUsingRemoveVariable)
{
    libcellml::ModelPtr m = libcellml::Model::create();
    libcellml::ComponentPtr comp1 = libcellml::Component::create();

    libcellml::VariablePtr v1 = libcellml::Variable::create();

    m->setName("modelName");
    comp1->setName("component1");

    v1->setName("variable1");

    v1->setUnits("dimensionless");

    comp1->addVariable(v1);
    m->addComponent(comp1);

    EXPECT_TRUE(v1->hasParent());
    // Make a variable without a parent component.
    comp1->removeVariable(v1);

    EXPECT_EQ(size_t(0), comp1->variableCount());
    EXPECT_FALSE(v1->hasParent());
    EXPECT_EQ(nullptr, v1->parent());
}

TEST(Variable, parentlessUsingRemoveAllVariables)
{
    libcellml::ModelPtr m = libcellml::Model::create();
    libcellml::ComponentPtr comp1 = libcellml::Component::create();

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    libcellml::VariablePtr v2 = libcellml::Variable::create();

    m->setName("modelName");
    comp1->setName("component1");

    v1->setName("variable1");
    v2->setName("variable2");

    v1->setUnits("dimensionless");
    v2->setUnits("dimensionless");

    comp1->addVariable(v1);
    comp1->addVariable(v2);
    m->addComponent(comp1);

    EXPECT_TRUE(v1->hasParent());
    EXPECT_TRUE(v2->hasParent());

    // Make a variable without a parent component.
    comp1->removeAllVariables();

    EXPECT_EQ(size_t(0), comp1->variableCount());
    EXPECT_FALSE(v1->hasParent());
    EXPECT_FALSE(v2->hasParent());
    EXPECT_EQ(nullptr, v1->parent());
    EXPECT_EQ(nullptr, v2->parent());
}

TEST(Variable, removeIndirectEquivalence)
{
    libcellml::ModelPtr m = libcellml::Model::create();
    libcellml::ComponentPtr comp1 = libcellml::Component::create();

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    libcellml::VariablePtr v2 = libcellml::Variable::create();
    libcellml::VariablePtr v3 = libcellml::Variable::create();

    m->setName("modelName");
    comp1->setName("component1");

    v1->setName("variable1");
    v2->setName("variable2");
    v3->setName("variable3");

    v1->setUnits("dimensionless");
    v2->setUnits("dimensionless");
    v3->setUnits("dimensionless");

    comp1->addVariable(v1);
    comp1->addVariable(v2);
    comp1->addVariable(v3);
    m->addComponent(comp1);

    EXPECT_TRUE(v1->hasParent());
    EXPECT_TRUE(v2->hasParent());
    EXPECT_TRUE(v3->hasParent());

    // Make v1=v2=v3
    libcellml::Variable::addEquivalence(v2, v3);
    libcellml::Variable::addEquivalence(v1, v3);

    // All variables connected ...
    EXPECT_TRUE(v1->hasEquivalentVariable(v2, true));
    EXPECT_TRUE(v2->hasEquivalentVariable(v3, true));
    EXPECT_TRUE(v1->hasEquivalentVariable(v3, true));

    // ... but not directly through v1-v2
    EXPECT_FALSE(v1->hasEquivalentVariable(v2));
    EXPECT_TRUE(v1->hasEquivalentVariable(v3));
    EXPECT_TRUE(v2->hasEquivalentVariable(v3));

    // Attempt to remove v1=v2
    EXPECT_FALSE(libcellml::Variable::removeEquivalence(v1, v2));

    // But cannot remove indirect equivalence
    EXPECT_TRUE(v1->hasEquivalentVariable(v2, true));
    EXPECT_FALSE(v1->hasEquivalentVariable(v2)); // It never was anyway, no change here

    // Nothing else should have changed here
    EXPECT_TRUE(v1->hasEquivalentVariable(v3, true));
    EXPECT_TRUE(v2->hasEquivalentVariable(v3, true));
    EXPECT_TRUE(v1->hasEquivalentVariable(v3));
    EXPECT_TRUE(v2->hasEquivalentVariable(v3));
}

TEST(Variable, leaveExpiredVariable)
{
    libcellml::VariablePtr v1 = libcellml::Variable::create();
    libcellml::VariablePtr v2 = libcellml::Variable::create();
    libcellml::VariablePtr v3 = libcellml::Variable::create();
    libcellml::Variable::addEquivalence(v1, v2);
    v2.reset();
    libcellml::Variable::addEquivalence(v1, v3);
    EXPECT_FALSE(v1->hasEquivalentVariable(v2));
    EXPECT_TRUE(v1->hasEquivalentVariable(v3));
}

TEST(Variable, addEquivalenceFirstParameterNullptr)
{
    libcellml::ModelPtr m = libcellml::Model::create();
    libcellml::ComponentPtr comp1 = libcellml::Component::create();

    libcellml::VariablePtr v1 = libcellml::Variable::create();

    m->setName("modelName");
    comp1->setName("component1");

    v1->setName("variable1");

    v1->setUnits("dimensionless");

    comp1->addVariable(v1);

    m->addComponent(comp1);

    EXPECT_FALSE(libcellml::Variable::addEquivalence(nullptr, v1));
}

TEST(Variable, addEquivalenceSecondParameterNullptr)
{
    libcellml::ModelPtr m = libcellml::Model::create();
    libcellml::ComponentPtr comp1 = libcellml::Component::create();

    libcellml::VariablePtr v1 = libcellml::Variable::create();

    m->setName("modelName");
    comp1->setName("component1");

    v1->setName("variable1");

    v1->setUnits("dimensionless");

    comp1->addVariable(v1);

    m->addComponent(comp1);

    EXPECT_FALSE(libcellml::Variable::addEquivalence(v1, nullptr));
}

TEST(Variable, addEquivalenceBothParametersNullptr)
{
    EXPECT_FALSE(libcellml::Variable::addEquivalence(nullptr, nullptr));
}

TEST(Variable, removeEquivalenceFirstParametersNullptr)
{
    libcellml::ModelPtr m = libcellml::Model::create();
    libcellml::ComponentPtr comp1 = libcellml::Component::create();

    libcellml::VariablePtr v1 = libcellml::Variable::create();

    m->setName("modelName");
    comp1->setName("component1");

    v1->setName("variable1");

    v1->setUnits("dimensionless");

    comp1->addVariable(v1);

    m->addComponent(comp1);

    EXPECT_FALSE(libcellml::Variable::removeEquivalence(nullptr, v1));
}

TEST(Variable, removeEquivalenceSecondParametersNullptr)
{
    libcellml::ModelPtr m = libcellml::Model::create();
    libcellml::ComponentPtr comp1 = libcellml::Component::create();

    libcellml::VariablePtr v1 = libcellml::Variable::create();

    m->setName("modelName");
    comp1->setName("component1");

    v1->setName("variable1");

    v1->setUnits("dimensionless");

    comp1->addVariable(v1);

    m->addComponent(comp1);

    EXPECT_FALSE(libcellml::Variable::removeEquivalence(v1, nullptr));
}

TEST(Variable, removeEquivalenceBothParametersNullptr)
{
    EXPECT_FALSE(libcellml::Variable::removeEquivalence(nullptr, nullptr));
}

TEST(Variable, hasEquivalentVariableWithNullptr)
{
    libcellml::ModelPtr m = libcellml::Model::create();
    libcellml::ComponentPtr c1 = libcellml::Component::create();
    libcellml::VariablePtr v1 = libcellml::Variable::create();

    m->setName("modelName");
    c1->setName("component1");
    v1->setName("variable1");
    v1->setUnits("dimensionless");

    c1->addVariable(v1);
    m->addComponent(c1);

    EXPECT_FALSE(v1->hasEquivalentVariable(nullptr));
}

TEST(Variable, variableEquivalenceInterface)
{
    libcellml::ModelPtr model = libcellml::Model::create();
    libcellml::ComponentPtr c1 = libcellml::Component::create();
    libcellml::ComponentPtr c2 = libcellml::Component::create();
    libcellml::ComponentPtr c3 = libcellml::Component::create();

    model->setName("model");
    c1->setName("c1");
    c2->setName("c2");
    c3->setName("c3");

    model->addComponent(c1);
    model->addComponent(c2);
    c2->addComponent(c3);

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName("v1");
    v1->setUnits("dimensionless");

    libcellml::VariablePtr v2 = libcellml::Variable::create();
    v2->setName("v2");
    v2->setUnits("dimensionless");

    libcellml::VariablePtr v3 = libcellml::Variable::create();
    v3->setName("v3");
    v3->setUnits("dimensionless");

    c1->addVariable(v1);
    c2->addVariable(v2);
    c3->addVariable(v3);

    libcellml::Variable::addEquivalence(v1, v2);
    libcellml::Variable::addEquivalence(v2, v3);

    EXPECT_TRUE(model->fixVariableInterfaces());

    EXPECT_EQ("public", v1->interfaceType());
    EXPECT_EQ("public_and_private", v2->interfaceType());
    EXPECT_EQ("public", v3->interfaceType());
}

TEST(Variable, variableEquivalencePublicInterface)
{
    libcellml::ModelPtr model = libcellml::Model::create();
    libcellml::ComponentPtr c1 = libcellml::Component::create();
    libcellml::ComponentPtr c2 = libcellml::Component::create();

    model->setName("model");
    c1->setName("c1");
    c2->setName("c2");

    model->addComponent(c1);
    model->addComponent(c2);

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName("v1");
    v1->setUnits("dimensionless");

    libcellml::VariablePtr v2 = libcellml::Variable::create();
    v2->setName("v2");
    v2->setUnits("dimensionless");

    c1->addVariable(v1);
    c2->addVariable(v2);

    libcellml::Variable::addEquivalence(v1, v2);

    EXPECT_TRUE(model->fixVariableInterfaces());

    EXPECT_EQ("public", v1->interfaceType());
    EXPECT_EQ("public", v2->interfaceType());
}

TEST(Variable, variableEquivalencePrivateInterface)
{
    libcellml::ModelPtr model = libcellml::Model::create();
    libcellml::ComponentPtr c1 = libcellml::Component::create();
    libcellml::ComponentPtr c2 = libcellml::Component::create();

    model->setName("model");
    c1->setName("c1");
    c2->setName("c2");

    model->addComponent(c1);
    c1->addComponent(c2);

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName("v1");
    v1->setUnits("dimensionless");

    libcellml::VariablePtr v2 = libcellml::Variable::create();
    v2->setName("v2");
    v2->setUnits("dimensionless");

    c1->addVariable(v1);
    c2->addVariable(v2);

    libcellml::Variable::addEquivalence(v1, v2);

    EXPECT_TRUE(model->fixVariableInterfaces());

    EXPECT_EQ("private", v1->interfaceType());
    EXPECT_EQ("public", v2->interfaceType());
}

TEST(Variable, variableEquivalencePublicAndPrivateInterface)
{
    libcellml::ModelPtr model = libcellml::Model::create();
    libcellml::ComponentPtr c1 = libcellml::Component::create();
    libcellml::ComponentPtr c2 = libcellml::Component::create();
    libcellml::ComponentPtr c3 = libcellml::Component::create();

    model->setName("model");
    c1->setName("c1");
    c2->setName("c2");
    c3->setName("c3");

    model->addComponent(c1);
    c1->addComponent(c2);
    c2->addComponent(c3);

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName("v1");
    v1->setUnits("dimensionless");

    libcellml::VariablePtr v2 = libcellml::Variable::create();
    v2->setName("v2");
    v2->setUnits("dimensionless");

    libcellml::VariablePtr v3 = libcellml::Variable::create();
    v3->setName("v3");
    v3->setUnits("dimensionless");

    c1->addVariable(v1);
    c2->addVariable(v2);
    c3->addVariable(v3);

    libcellml::Variable::addEquivalence(v1, v2);
    libcellml::Variable::addEquivalence(v3, v2);

    EXPECT_TRUE(model->fixVariableInterfaces());

    EXPECT_EQ("private", v1->interfaceType());
    EXPECT_EQ("public_and_private", v2->interfaceType());
    EXPECT_EQ("public", v3->interfaceType());
}

TEST(Variable, distantVariableEquivalence)
{
    libcellml::ModelPtr model = libcellml::Model::create();
    libcellml::ComponentPtr c1 = libcellml::Component::create();
    libcellml::ComponentPtr c2 = libcellml::Component::create();
    libcellml::ComponentPtr c3 = libcellml::Component::create();

    model->setName("model");
    c1->setName("c1");
    c2->setName("c2");
    c3->setName("c3");

    model->addComponent(c1);
    c1->addComponent(c2);
    c2->addComponent(c3);

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName("v1");
    v1->setUnits("dimensionless");

    libcellml::VariablePtr v2 = libcellml::Variable::create();
    v2->setName("v2");
    v2->setUnits("dimensionless");

    libcellml::VariablePtr v3 = libcellml::Variable::create();
    v3->setName("v3");
    v3->setUnits("dimensionless");

    c1->addVariable(v1);
    c2->addVariable(v2);
    c3->addVariable(v3);

    libcellml::Variable::addEquivalence(v1, v3);

    EXPECT_FALSE(model->fixVariableInterfaces());

    // Couldn't determine interface types for variables that are
    // too distant from each other in the component hierarchy.
    EXPECT_EQ("", v1->interfaceType());
    EXPECT_EQ("", v3->interfaceType());
}

TEST(Variable, variableEquivalencePromoteFromPrivate)
{
    libcellml::ModelPtr model = libcellml::Model::create();
    libcellml::ComponentPtr c1 = libcellml::Component::create();
    libcellml::ComponentPtr c2 = libcellml::Component::create();

    model->setName("model");
    c1->setName("c1");
    c2->setName("c2");

    model->addComponent(c1);
    c1->addComponent(c2);

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName("v1");
    v1->setUnits("dimensionless");

    libcellml::VariablePtr v2 = libcellml::Variable::create();
    v2->setName("v2");
    v2->setUnits("dimensionless");

    c1->addVariable(v1);
    c2->addVariable(v2);

    v2->setInterfaceType("private");

    libcellml::Variable::addEquivalence(v1, v2);

    EXPECT_TRUE(model->fixVariableInterfaces());

    EXPECT_EQ("private", v1->interfaceType());
    EXPECT_EQ("public", v2->interfaceType());
}

TEST(Variable, variableInterfaceDontDowngrade)
{
    libcellml::ModelPtr model = libcellml::Model::create();
    libcellml::ComponentPtr c1 = libcellml::Component::create();
    libcellml::ComponentPtr c2 = libcellml::Component::create();
    libcellml::ComponentPtr c3 = libcellml::Component::create();
    libcellml::ComponentPtr c4 = libcellml::Component::create();

    model->setName("model");
    c1->setName("c1");
    c2->setName("c2");
    c3->setName("c3");
    c4->setName("c4");

    model->addComponent(c1);
    model->addComponent(c4);
    c1->addComponent(c2);
    c2->addComponent(c3);

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName("v1");
    v1->setUnits("dimensionless");
    v1->setInterfaceType("public");

    libcellml::VariablePtr v3 = libcellml::Variable::create();
    v3->setName("v3");
    v3->setUnits("dimensionless");

    libcellml::VariablePtr v4 = libcellml::Variable::create();
    v4->setName("v4");
    v4->setUnits("dimensionless");

    c1->addVariable(v1);
    c3->addVariable(v3);
    c4->addVariable(v4);

    libcellml::Variable::addEquivalence(v1, v4);
    libcellml::Variable::addEquivalence(v1, v3);

    EXPECT_FALSE(model->fixVariableInterfaces());

    EXPECT_EQ("public", v1->interfaceType());
    EXPECT_EQ("", v3->interfaceType());
    EXPECT_EQ("public", v4->interfaceType());
}

TEST(Variable, variableInterfaceDontDowngradeFromPublicAndPrivate)
{
    libcellml::ModelPtr model = libcellml::Model::create();
    libcellml::ComponentPtr c1 = libcellml::Component::create();
    libcellml::ComponentPtr c2 = libcellml::Component::create();
    libcellml::ComponentPtr c3 = libcellml::Component::create();

    model->setName("model");
    c1->setName("c1");
    c2->setName("c2");
    c3->setName("c3");

    model->addComponent(c1);
    c1->addComponent(c2);
    c2->addComponent(c3);

    libcellml::VariablePtr v1 = libcellml::Variable::create();
    v1->setName("v1");
    v1->setUnits("dimensionless");
    v1->setInterfaceType("public_and_private");

    libcellml::VariablePtr v2 = libcellml::Variable::create();
    v2->setName("v2");
    v2->setUnits("dimensionless");

    libcellml::VariablePtr v3 = libcellml::Variable::create();
    v3->setName("v3");
    v3->setUnits("dimensionless");

    c1->addVariable(v1);
    c2->addVariable(v2);
    c3->addVariable(v3);

    libcellml::Variable::addEquivalence(v1, v2);
    libcellml::Variable::addEquivalence(v2, v3);

    EXPECT_TRUE(model->fixVariableInterfaces());

    EXPECT_EQ("public_and_private", v1->interfaceType());
    EXPECT_EQ("public_and_private", v2->interfaceType());
    EXPECT_EQ("public", v3->interfaceType());
}

TEST(Variable, minimumInterfaceType)
{
    auto vPublic = libcellml::Variable::create("vPublic");
    vPublic->setInterfaceType("public");

    auto vPrivate = libcellml::Variable::create("vPrivate");
    vPrivate->setInterfaceType("private");

    auto vPublicAndPrivate = libcellml::Variable::create("vPublicAndPrivate");
    vPublicAndPrivate->setInterfaceType("public_and_private");

    auto vNone = libcellml::Variable::create("vNone");
    vNone->setInterfaceType("none");

    auto vEmpty = libcellml::Variable::create("vEmpty");

    // Stored public_and_private meets all requirements.
    EXPECT_TRUE(vPublicAndPrivate->permitsInterfaceType(libcellml::Variable::InterfaceType::NONE));
    EXPECT_TRUE(vPublicAndPrivate->permitsInterfaceType(libcellml::Variable::InterfaceType::PRIVATE));
    EXPECT_TRUE(vPublicAndPrivate->permitsInterfaceType(libcellml::Variable::InterfaceType::PUBLIC));
    EXPECT_TRUE(vPublicAndPrivate->permitsInterfaceType(libcellml::Variable::InterfaceType::PUBLIC_AND_PRIVATE));

    // Stored private meets private and none requirements.
    EXPECT_TRUE(vPrivate->permitsInterfaceType(libcellml::Variable::InterfaceType::NONE));
    EXPECT_TRUE(vPrivate->permitsInterfaceType(libcellml::Variable::InterfaceType::PRIVATE));
    EXPECT_FALSE(vPrivate->permitsInterfaceType(libcellml::Variable::InterfaceType::PUBLIC));
    EXPECT_FALSE(vPrivate->permitsInterfaceType(libcellml::Variable::InterfaceType::PUBLIC_AND_PRIVATE));

    // Stored public meets public and none requirements.
    EXPECT_TRUE(vPublic->permitsInterfaceType(libcellml::Variable::InterfaceType::NONE));
    EXPECT_FALSE(vPublic->permitsInterfaceType(libcellml::Variable::InterfaceType::PRIVATE));
    EXPECT_TRUE(vPublic->permitsInterfaceType(libcellml::Variable::InterfaceType::PUBLIC));
    EXPECT_FALSE(vPublic->permitsInterfaceType(libcellml::Variable::InterfaceType::PUBLIC_AND_PRIVATE));

    // Stored none meets none requirements.
    EXPECT_TRUE(vNone->permitsInterfaceType(libcellml::Variable::InterfaceType::NONE));
    EXPECT_FALSE(vNone->permitsInterfaceType(libcellml::Variable::InterfaceType::PRIVATE));
    EXPECT_FALSE(vNone->permitsInterfaceType(libcellml::Variable::InterfaceType::PUBLIC));
    EXPECT_FALSE(vNone->permitsInterfaceType(libcellml::Variable::InterfaceType::PUBLIC_AND_PRIVATE));

    // Stored empty meets none requirements.
    EXPECT_TRUE(vEmpty->permitsInterfaceType(libcellml::Variable::InterfaceType::NONE));
    EXPECT_FALSE(vEmpty->permitsInterfaceType(libcellml::Variable::InterfaceType::PRIVATE));
    EXPECT_FALSE(vEmpty->permitsInterfaceType(libcellml::Variable::InterfaceType::PUBLIC));
    EXPECT_FALSE(vEmpty->permitsInterfaceType(libcellml::Variable::InterfaceType::PUBLIC_AND_PRIVATE));
}

TEST(Variable, connectionsPersistAfterImporting)
{
    auto model = libcellml::Model::create("model");
    auto importer = libcellml::Importer::create();

    auto importedComponent = libcellml::Component::create("importedComponent");
    model->addComponent(importedComponent);

    auto importSource = libcellml::ImportSource::create();
    importSource->setUrl("importedModelWithMaps.cellml");
    importedComponent->setImportSource(importSource);
    importedComponent->setImportReference("importMe");

    EXPECT_TRUE(model->hasUnresolvedImports());
    importer->resolveImports(model, resourcePath());
    EXPECT_FALSE(model->hasUnresolvedImports());

    model = importer->flattenModel(model);

    EXPECT_NE(nullptr, model->component("importedComponent"));
    EXPECT_NE(nullptr, model->component("importedComponent")->component("child1"));
    EXPECT_NE(nullptr, model->component("importedComponent")->component("child2"));
    EXPECT_NE(nullptr, model->component("importedComponent")->component("child1")->variable("x"));
    EXPECT_NE(nullptr, model->component("importedComponent")->component("child2")->variable("x"));

    auto x1 = model->component("importedComponent")->component("child1")->variable("x");
    auto x2 = model->component("importedComponent")->component("child2")->variable("x");
    EXPECT_EQ(size_t(1), x1->equivalentVariableCount());
    EXPECT_EQ(size_t(1), x2->equivalentVariableCount());
    EXPECT_EQ(x1, x2->equivalentVariable(0));
    EXPECT_EQ(x2, x1->equivalentVariable(0));
}

TEST(Variable, addVariableDuplicates)
{
    auto model = libcellml::Model::create("model");
    auto tomato = libcellml::Component::create("tomato");
    auto apple = libcellml::Component::create("apple");
    auto pip = libcellml::Variable::create("pip");

    EXPECT_TRUE(model->addComponent(tomato));
    EXPECT_TRUE(model->addComponent(apple));

    // Adding a pip to the tomato.
    EXPECT_TRUE(tomato->addVariable(pip));
    EXPECT_EQ(size_t(1), tomato->variableCount());

    // Add the same pip again.
    EXPECT_TRUE(tomato->addVariable(pip));
    EXPECT_EQ(size_t(2), tomato->variableCount());

    // Add the same pip to the apple this time, which will effectively move it
    // from the tomato to the apple. Leaving one pip in the tomato.
    EXPECT_TRUE(apple->addVariable(pip));

    EXPECT_EQ(size_t(1), apple->variableCount());
    EXPECT_EQ(size_t(1), tomato->variableCount());
}

TEST(Variable, addEquivalenceReturnsFalseProperly)
{
    auto m = libcellml::Model::create("m");
    auto c1 = libcellml::Component::create("c1");
    auto c2 = libcellml::Component::create("c2");
    auto v1 = libcellml::Variable::create("v1");
    auto v2 = libcellml::Variable::create("v2");

    EXPECT_TRUE(m->addComponent(c1));
    EXPECT_TRUE(m->addComponent(c2));
    EXPECT_TRUE(c1->addVariable(v1));
    EXPECT_TRUE(c2->addVariable(v2));

    // Create a connection with self variable, expect no connections have been created.
    EXPECT_FALSE(libcellml::Variable::addEquivalence(v1, v1));
    EXPECT_EQ(size_t(0), v1->equivalentVariableCount());

    // Create a connection with one nullptr, expect no connections have been created.
    EXPECT_FALSE(libcellml::Variable::addEquivalence(v2, nullptr));
    EXPECT_EQ(size_t(0), v2->equivalentVariableCount());
}


text:
package com.solvetec.derek.tides;

import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.CursorLoader;
import androidx.loader.content.Loader;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.solvetec.derek.tides.dfo_REST.Station;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.solvetec.derek.tides.data.TidesContract.TidesEntry;
import com.solvetec.derek.tides.utils.PredictionServiceHelper;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by Derek on 11/11/2017.
 */

public class MapPickerActivity extends AppCompatActivity implements
        OnMapReadyCallback,
        GoogleMap.OnMarkerClickListener,
        GoogleMap.OnMapClickListener,
        LoaderManager.LoaderCallbacks,
        View.OnClickListener{

    private GoogleMap mMap;
    private Marker mSelectedMarker;
    private BottomSheetBehavior mBottomSheetBehavior;
    private TextView mTextViewStationName;
    private TextView mTextViewStationId;
    private TextView mTextViewStationLatLon;
    private Button mButtonSelectLocation;

    private Map<String, Station> mStationsMap;
    private String mPrefStationId;
    private Station mPrefStation;
    private Marker mOldPrefMarker;

    private static final String PROJECTION_KEY = "PROJECTION_KEY";
    private static final int ID_STATIONS_LOADER = 50;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map_picker);

        // Get settings
        Context appContext = getApplicationContext();
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(appContext);
        mPrefStationId = prefs.getString(getString(R.string.pref_location_key), getString(R.string.pref_location_default));

        // Load stations from db
        Bundle stationsBundle = new Bundle();
        stationsBundle.putStringArray(PROJECTION_KEY, new String[] {
                TidesEntry.COLUMN_STATION_ID,
                TidesEntry.COLUMN_STATION_NAME,
                TidesEntry.COLUMN_STATION_LON,
                TidesEntry.COLUMN_STATION_LAT,
                TidesEntry.COLUMN_STATION_TIMEZONE_ID});
        getSupportLoaderManager().initLoader(ID_STATIONS_LOADER, stationsBundle, this);

//        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
//                .findFragmentById(R.id.map_picker_fragment);
//        mapFragment.getMapAsync(this);

        // Setup bottom sheet
        View bottomSheetFrame = findViewById(R.id.frame_bottom_sheet);
        mBottomSheetBehavior = BottomSheetBehavior.from(bottomSheetFrame);
        mBottomSheetBehavior.setHideable(true);
        mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);

        mTextViewStationName = findViewById(R.id.tv_map_station_name);
        mTextViewStationId = findViewById(R.id.tv_map_station_id);
        mTextViewStationLatLon = findViewById(R.id.tv_map_station_latlon);
        mButtonSelectLocation = findViewById(R.id.button_map_select_location);
        mButtonSelectLocation.setOnClickListener(this);

    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        // Disable quick settings that interfere with my bottom bar
        mMap.getUiSettings().setMapToolbarEnabled(false);

        // Load all markers
        List<Station> stationsList = (new ArrayList<>(mStationsMap.values()));
        mOldPrefMarker = null;
        for(int i = 0; i < mStationsMap.size(); i++) {
            Station station = stationsList.get(i);
            LatLng location = new LatLng(station.latitude, station.longitude);
            Marker marker = mMap.addMarker(new MarkerOptions().position(location).title(station.station_name));
            if(station.station_id.equals(mPrefStationId)) {
                mPrefStation = new Station(station);
                mOldPrefMarker = marker;
            }

            // Attach data to each marker
            marker.setTag(station);
        }

        // Change color of currently selected station marker
        if(mOldPrefMarker != null) {
            mOldPrefMarker.setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
        }

        // Set marker click listeners
        mMap.setOnMarkerClickListener(this);
        mMap.setOnMapClickListener(this);

        // Pick starting camera
        float zoomLevel = 9;
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
                new LatLng(mPrefStation.latitude, mPrefStation.longitude),
                zoomLevel));

    }

    @Override
    public Loader onCreateLoader(int id, Bundle args) {
        switch (id) {
            case ID_STATIONS_LOADER:
                Uri stationsQueryUri = TidesEntry.STATION_INFO_CONTENT_URI;
                return new CursorLoader(this,
                        stationsQueryUri,
                        args.getStringArray(PROJECTION_KEY),
                        null,
                        null,
                        null);
            default:
                throw new RuntimeException("Loader not implemented: " + id);
        }
    }

    @Override
    public void onLoadFinished(Loader loader, Object data) {
        Cursor dataCursor = (Cursor) data;
        switch(loader.getId()) {
            case ID_STATIONS_LOADER:
                if (dataCursor.getCount() != 0) {
                    mStationsMap = PredictionServiceHelper.parseStationCursor(dataCursor);

                    // Start map here, to ensure data is loaded
                    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                        .findFragmentById(R.id.map_picker_fragment);
                    mapFragment.getMapAsync(this);
                }
                break;
            default:
                throw new RuntimeException("Loader not implemented: " + loader.getId());
        }
    }

    @Override
    public void onLoaderReset(Loader loader) {

    }

    @Override
    public boolean onMarkerClick(Marker marker) {
        if(mSelectedMarker != null) {
            // Reset previously selected marker
            if(mSelectedMarker.equals(mOldPrefMarker)) {
                mSelectedMarker.setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
            } else {
                mSelectedMarker.setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
            }
        }

        // Set marker to SelectedColor
        mSelectedMarker = marker;
        mSelectedMarker.setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));

        // Bring up bottom sheet
        mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);

        // Load data for bottom sheet
        Station station = (Station) mSelectedMarker.getTag();
        if(station != null) {
            mTextViewStationName.setText(station.station_name);
            mTextViewStationId.setText(station.station_id);
            String latlon = Double.toString(station.latitude) + ", " + Double.toString(station.longitude);
            mTextViewStationLatLon.setText(latlon);
        }

        return false; // Don't consume markerClick. Allow camera to center on selected marker.
    }

    @Override
    public void onMapClick(LatLng latLng) {
        // Reset previously selected marker
        if(mSelectedMarker != null) {
            if(mSelectedMarker.equals(mOldPrefMarker)) {
                mSelectedMarker.setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
            } else {
                mSelectedMarker.setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
            }
            // Bring down bottom sheet
            mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
        }
        mSelectedMarker = null;
    }

    // Button click listener
    @Override
    public void onClick(View v) {
        // If button pressed, and there is a marker selected
        if(v.equals(mButtonSelectLocation) && mSelectedMarker != null) {
            // Save new preferredLocation
            Context appContext = getApplicationContext();
            Station station = (Station) mSelectedMarker.getTag();
            if(station == null) {
                return;
            }

            SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(appContext).edit();
            editor.putString(getString(R.string.pref_location_key), station.station_id);
            editor.commit();

            // Exit back to main page
            onBackPressed();
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
USE Libry
GO
SELECT BorrowerName as 'Borrowers with no check-outs'
FROM Borrowers
LEFT JOIN BookLoans ON Borrowers.BorrowerId = BookLoans.BorrowerId
WHERE BookId IS NULL
ORDER BY BorrowerName
GO


text:
layout: page
title: Linda Bauer's 39th Birthday
date: 2016-05-24
author: Teresa Fowler
tags: weekly links, java
status: published
summary: Duis euismod risus sed ullamcorper suscipit. Quisque tincidunt sed felis.
banner: images/banner/meeting-01.jpg
booking:
  startDate: 10/15/2019
  endDate: 10/18/2019
  ctyhocn: YEGHSHX
  groupCode: LB3B
published: true
---
Donec lectus dui, facilisis eu volutpat sed, pulvinar vitae augue. Nullam tempus ex vel aliquet maximus. Nulla blandit purus quis vulputate semper. Fusce vel nibh ultricies, cursus odio vitae, facilisis ipsum. Nullam nulla enim, bibendum in sollicitudin quis, varius finibus arcu. Etiam tincidunt tellus sem, sed convallis ipsum efficitur at. Donec id eros pulvinar, commodo velit ut, porta odio.

* Aliquam at justo eget enim pharetra pharetra sed at nibh
* Vestibulum sed turpis eget ligula dictum malesuada luctus nec lorem
* Aliquam id neque non est dictum placerat
* Suspendisse ut risus dignissim enim tempus rhoncus ut a eros
* Sed et odio et odio semper ullamcorper
* Duis ullamcorper lectus eleifend felis vulputate, eget hendrerit libero sodales.

Aliquam interdum a nibh accumsan eleifend. Nulla ultrices, dolor ut fermentum scelerisque, urna magna elementum ex, vulputate accumsan ipsum risus viverra neque. Duis cursus, enim at convallis sollicitudin, dolor nibh viverra velit, sed maximus diam elit convallis est. Donec luctus iaculis mauris, scelerisque elementum mauris tempus a. Ut viverra mauris turpis, dignissim vulputate ipsum laoreet eu. Aenean egestas urna eu aliquet iaculis. Cras eleifend metus mauris, vitae feugiat leo suscipit nec. Cras rutrum consequat sapien dignissim consectetur.


text:
package abra.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;

import htsjdk.samtools.CigarElement;
import htsjdk.samtools.CigarOperator;
import htsjdk.samtools.SAMFileReader;
import htsjdk.samtools.ValidationStringency;
import htsjdk.samtools.SAMRecord;
import htsjdk.samtools.util.CloseableIterator;

public class CalcMismatchDensity {

	private String ref;
	private String baseDir;
	private String inputFile;
	private String currPid = "";
	private String origBam;
	private String abraBam;
	private CompareToReference3 c2r;
	private int minBaseQuality = 20;
	private int readLength;

	public CalcMismatchDensity(String ref, String baseDir, String inputFile, String origBam, String abraBam, int readLength) {
		this.ref = ref;
		this.baseDir = baseDir;
		this.inputFile = inputFile;
		this.origBam = origBam;
		this.abraBam = abraBam;
		this.readLength = readLength;
	}

	public void run() throws IOException {

		System.err.println("Loading reference");
		c2r = new CompareToReference3();
		c2r.init(ref);
		c2r.setMinBaseQuality(20);

		BufferedReader reader = new BufferedReader(new FileReader(inputFile));

		SAMFileReader abraReader = null;
		SAMFileReader origReader = null;

		long s = System.currentTimeMillis();

		String line = reader.readLine();
		while (line != null) {
			String[] fields = line.split("\t");
			String pid = fields[1];
			if (!pid.equals(currPid)) {
				currPid = pid;
				System.err.println(currPid);
				abraReader = initReader(abraReader, baseDir + "/" + pid + "/" + abraBam);
				origReader = initReader(origReader, baseDir + "/" + pid + "/" + origBam);
			}

			String chromosome = fields[2];
			int pos = Integer.parseInt(fields[3]);
			int refLen = Integer.parseInt(fields[5]);
			int altLen = Integer.parseInt(fields[6]);
			int length = 0;
			CigarOperator indelType;

			if (refLen > 1) {
				indelType = CigarOperator.D;
				length = refLen - 1;
			} else if (altLen > 1) {
				indelType = CigarOperator.I;
				length = altLen - 1;
			} else {
				throw new IllegalArgumentException("Not an indel: " + line);
			}

			double abraMd = calcMismatchDensity(abraReader, indelType, chromosome, pos, length);
			double origMd = calcMismatchDensity(origReader, indelType, chromosome, pos, length);

			System.out.println(line + "\t" + abraMd + "\t" + origMd);

			line = reader.readLine();
		}

		reader.close();

		long e = System.currentTimeMillis();

//		System.out.println("Elapsed: " + (e-s));
	}

	private double calcMismatchDensity(SAMFileReader reader, CigarOperator indelType, String chromosome, int pos, int length) {

		int numMismatches = 0;
		int numBases = 0;

		CloseableIterator<SAMRecord> iter =  reader.queryOverlapping(chromosome, pos-readLength, pos+length+readLength);

		while (iter.hasNext()) {
			SAMRecord read = (SAMRecord) iter.next();

//			String yo = (String) read.getAttribute("YO");

//			if ((yo == null) || (!yo.equals("N/A"))) {
				numMismatches += c2r.noiseAroundIndel(read, indelType, pos, length);

				for (int qual : read.getBaseQualities()) {
	//				qual = qual - '!';
					if (qual >= minBaseQuality) {
						numBases += 1;
					}
				}
//			}
		}

		iter.close();

		return numBases == 0 ? 0.0 : (double) numMismatches / (double) numBases;
	}

	private SAMFileReader initReader(SAMFileReader old, String input) {
		if (old != null) {
			old.close();
		}

		SAMFileReader reader = new SAMFileReader(new File(input));
		reader.setValidationStringency(ValidationStringency.SILENT);

		return reader;
	}

	public static void main(String[] args) throws Exception {
		String ref = args[0];
		String baseDir = args[1];
		String inputFile = args[2];
		String origBam = args[3];
		String abraBam = args[4];
		int readLength = Integer.parseInt(args[5]);

//		String ref = "/home/lmose/reference/chr1/1.fa";
//		String baseDir = "/home/lmose/dev/ayc/mismatch_density";
//		String inputFile = "/home/lmose/dev/ayc/mismatch_density/gl.txt";
//		String origBam = "n1.bam";
//		String abraBam = "n.abra.1.bam";
//		int readLength = 100;

		CalcMismatchDensity cmd = new CalcMismatchDensity(ref, baseDir, inputFile, origBam, abraBam, readLength);

		cmd.run();

		System.err.println("Done.");
	}
}


text:
#region Apache Notice

#endregion

using System;
using System.Collections;

namespace IBatisNet.Common.Pagination
{
	/// <summary>
	/// Summary description for IPaginatedList.
	/// </summary>
	public interface IPaginatedList : IList, IEnumerator
	{

		/// <summary>
		/// The maximum number of items per page.
		/// </summary>
		int PageSize
		{
			get;
		}

		/// <summary>
		/// Is the current page the first page ?
		/// True if the current page is the first page or if only
		/// a single page exists.
		/// </summary>
		bool IsFirstPage
		{
			get;
		}

		/// <summary>
		/// Is the current page a middle page (i.e. not first or last) ?
		/// Return True if the current page is not the first or last page,
		/// and more than one page exists (always returns false if only a
		/// single page exists).
		/// </summary>
		bool IsMiddlePage
		{
			get;
		}

		/// <summary>
		/// Is the current page the last page ?
		/// Return True if the current page is the last page or if only
		/// a single page exists.
		/// </summary>
		bool IsLastPage
		{
			get;
		}

		/// <summary>
		/// Is a page available after the current page ?
		/// Return True if the next page is available
		/// </summary>
		bool IsNextPageAvailable
		{
			get;
		}

		/// <summary>
		/// Is a page available before the current page ?
		/// Return True if the previous page is available
		/// </summary>
		bool IsPreviousPageAvailable
		{
			get;
		}

		/// <summary>
		/// Moves to the next page after the current page.  If the current
		/// page is the last page, wrap to the first page.
		/// </summary>
		/// <returns></returns>
		bool NextPage();

		/// <summary>
		/// Moves to the page before the current page.  If the current
		/// page is the first page, wrap to the last page.
		/// </summary>
		/// <returns></returns>
		bool PreviousPage();

		/// <summary>
		/// Moves to a specified page.  If the specified
		/// page is beyond the last page, wrap to the first page.
		/// If the specified page is before the first page, wrap
		/// to the last page.
		/// </summary>
		/// <param name="pageIndex">The index of the specified page.</param>
		void GotoPage(int pageIndex);

		/// <summary>
		/// Returns the current page index, which is a zero based integer.
		/// All paginated list implementations should know what index they are
		/// on, even if they don't know the ultimate boundaries (min/max)
		/// </summary>
		int PageIndex
		{
			get;
		}

	}
}


text:
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;

typedef int intptr_t;
typedef unsigned int uintptr_t;

typedef int ptrdiff_t;

typedef unsigned int size_t;

#define NULL 0

#endif


text:
//
// This code was auto-generated by AFNOR StoredProcedureSystem, version 1.0
//

using SOURCE.Domaine;
using System.Linq;

namespace SOURCE.Business.Depots
{
    public partial interface IDepotOperateur : IDepot<Operateur>
    {

    }
}


text:
<<<<<<< HEAD
<?php
  // controlador de mis apuntes por Raul Villar

  session_start(); // iniciar sesion

  //Includes iniciales
  require_once '../views/templateEngine.php'; // se carga la clase TemplateEngine
  require_once '../model/driver.php'; // se carga el driver de cancerbero
  require_once 'navbar.php'; //Inclusión de navbar. Omitible si no la necesita
  require_once '../model/Usuario.php';
  require_once '../model/Materia.php';
  require_once '../model/Titulacion.php';
  require_once 'comboboxes.php';
  //Conexion a la BD
  $db = Driver::getInstance();
  //inicio instancias render y creacion de comboboxes
  $usuario = new Usuario($db);
  $usuario = $usuario->findBy('user_name',$_SESSION['name']);
  $usuario = $usuario[0];
  $materias = new Materia($db);
  $titulaciones = new Titulacion($db);
  $materias = $materias->all();
  $titulaciones = $titulaciones->all();
  //Instancias TemplateEngine, renderizan elementos
  $renderMain = new TemplateEngine();
  $renderPlantilla = new TemplateEngine();
  $apuntes = $usuario->apuntes();
  $tieneapuntes = $usuario->tieneApuntes();
  $renderPlantilla->titulos = null;
  $renderPlantilla->materias = $materias;
  $renderPlantilla->anho = anhoRenderComboBox();
  //fin Instancias
  //FUNCIONES DEL CONTROLADOR
  if( isset($_POST['materia']) || isset($_POST['anho']) ){
     if($_POST['materia'] != "nil"){
       $materiafiltro = new Materia($db);
       $materiafiltro = $materiafiltro->findBy('mat_name',$_POST['materia']);
       if($materiafiltro){
         $materiafiltro = $materiafiltro[0];

       foreach ($apuntes as $key => $apunte) {
         if($apunte->getMat_id() != $materiafiltro->getMat_id()){
           unset($apuntes[$key]);
         }
      }
      foreach ($tieneapuntes as $key => $apunte) {
        if($apunte->getMat_id() != $materiafiltro->getMat_id()){
          unset($tieneapuntes[$key]);
        }
     }
    }}
    if($_POST['anho'] != "nil"){
      foreach ($apuntes as $key => $apunte) {
        if($apunte->getAnho_academico() != $_POST['anho']){
          unset($apuntes[$key]);
        }
     }
     foreach ($tieneapuntes as $key => $apunte) {
       if($apunte->getAnho_academico() != $_POST['anho']){
         unset($tieneapuntes[$key]);
       }
    }
    }
  }
  $renderPlantilla->apuntes = $apuntes;
  $renderPlantilla->tieneapuntes = $tieneapuntes;
  //RENDERIZADO FINAL
  $renderMain->title = "Mis Apuntes"; //Titulo y cabecera de la pagina
  $renderMain->navbar = renderNavBar(); //Inserción de navBar en la pagina. Omitible si no la necesita
  $renderMain->content = $renderPlantilla->render('misApuntes_v.php'); //Inserción del contenido de la página

  echo $renderMain->renderMain(); // Dibujado de la página al completo

 ?>
=======
<?php
  // controlador de mis apuntes por Raul Villar

  session_start(); // iniciar sesion

  //Includes iniciales
  require_once '../views/templateEngine.php'; // se carga la clase TemplateEngine
  require_once '../model/driver.php'; // se carga el driver de cancerbero
  require_once 'navbar.php'; //Inclusión de navbar. Omitible si no la necesita
  require_once '../model/Usuario.php';
  require_once '../model/Materia.php';
  require_once '../model/Titulacion.php';
  require_once 'comboboxes.php';
  //Conexion a la BD
  $db = Driver::getInstance();
  //inicio instancias render y creacion de comboboxes
  $usuario = new Usuario($db);
  $usuario = $usuario->findBy('user_name',$_SESSION['name']);
  $usuario = $usuario[0];
  $materias = new Materia($db);
  $titulaciones = new Titulacion($db);
  $materias = $materias->all();
  $titulaciones = $titulaciones->all();
  //Instancias TemplateEngine, renderizan elementos
  $renderMain = new TemplateEngine();
  $renderPlantilla = new TemplateEngine();
  $apuntes = $usuario->apuntes();
  $tieneapuntes = $usuario->tieneApuntes();
  $renderPlantilla->titulos = null;
  $renderPlantilla->materias = $materias;
  $renderPlantilla->anho = anhoRenderComboBox();
  //fin Instancias
  //FUNCIONES DEL CONTROLADOR
  if( isset($_POST['materia']) || isset($_POST['anho']) ){
     if($_POST['materia'] != "nil"){
       $materiafiltro = new Materia($db);
       $materiafiltro = $materiafiltro->findBy('mat_name',$_POST['materia']);
       if($materiafiltro){
         $materiafiltro = $materiafiltro[0];

       foreach ($apuntes as $key => $apunte) {
         if($apunte->getMat_id() != $materiafiltro->getMat_id()){
           unset($apuntes[$key]);
         }
      }
      foreach ($tieneapuntes as $key => $apunte) {
        if($apunte->getMat_id() != $materiafiltro->getMat_id()){
          unset($tieneapuntes[$key]);
        }
     }
    }}
    if($_POST['anho'] != "nil"){
      foreach ($apuntes as $key => $apunte) {
        if($apunte->getAnho_academico() != $_POST['anho']){
          unset($apuntes[$key]);
        }
     }
     foreach ($tieneapuntes as $key => $apunte) {
       if($apunte->getAnho_academico() != $_POST['anho']){
         unset($tieneapuntes[$key]);
       }
    }
    }
  }
  $renderPlantilla->apuntes = $apuntes;
  $renderPlantilla->tieneapuntes = $tieneapuntes;
  //RENDERIZADO FINAL
  $renderMain->title = "Mis Apuntes"; //Titulo y cabecera de la pagina
  $renderMain->navbar = renderNavBar(); //Inserción de navBar en la pagina. Omitible si no la necesita
  $renderMain->content = $renderPlantilla->render('misApuntes_v.php'); //Inserción del contenido de la página

  echo $renderMain->renderMain(); // Dibujado de la página al completo

 ?>
>>>>>>> upstream/master