text:
using namespace std;

class CAddrManTest : public CAddrMan
{
    uint64_t state;

public:
    CAddrManTest()
    {
        state = 1;
    }

    //! Ensure that bucket placement is always the same for testing purposes.
    void MakeDeterministic()
    {
        nKey.SetNull();
        insecure_rand = FastRandomContext(true);
    }

    int RandomInt(int nMax)
    {
        state = (CHashWriter(SER_GETHASH, 0) << state).GetHash().GetCheapHash();
        return (unsigned int)(state % nMax);
    }

    CAddrInfo* Find(const CNetAddr& addr, int* pnId = NULL)
    {
        return CAddrMan::Find(addr, pnId);
    }

    CAddrInfo* Create(const CAddress& addr, const CNetAddr& addrSource, int* pnId = NULL)
    {
        return CAddrMan::Create(addr, addrSource, pnId);
    }

    void Delete(int nId)
    {
        CAddrMan::Delete(nId);
    }

    // Simulates connection failure so that we can test eviction of offline nodes
    void SimConnFail(CService& addr)
    {
         int64_t nLastSuccess = 1;
         Good_(addr, true, nLastSuccess); // Set last good connection in the deep past.

         bool count_failure = false;
         int64_t nLastTry = GetAdjustedTime()-61;
         Attempt(addr, count_failure, nLastTry);
     }
};

BOOST_FIXTURE_TEST_SUITE(addrman_tests, BasicTestingSetup)

BOOST_AUTO_TEST_CASE(addrman_simple)
{
    CAddrManTest addrman;

    // Set addrman addr placement to be deterministic.
    addrman.MakeDeterministic();

    CNetAddr source = CNetAddr("252.2.2.2");

    // Test 1: Does Addrman respond correctly when empty.
    BOOST_CHECK(addrman.size() == 0);
    CAddrInfo addr_null = addrman.Select();
    BOOST_CHECK(addr_null.ToString() == "[::]:0");

    // Test 2: Does Addrman::Add work as expected.
    CService addr1 = CService("250.1.1.1", 8333);
    addrman.Add(CAddress(addr1), source);
    BOOST_CHECK(addrman.size() == 1);
    CAddrInfo addr_ret1 = addrman.Select();
    BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333");

    // Test 3: Does IP address deduplication work correctly.
    //  Expected dup IP should not be added.
    CService addr1_dup = CService("250.1.1.1", 8333);
    addrman.Add(CAddress(addr1_dup), source);
    BOOST_CHECK(addrman.size() == 1);

    // Test 5: New table has one addr and we add a diff addr we should
    //  have two addrs.
    CService addr2 = CService("250.1.1.2", 8333);
    addrman.Add(CAddress(addr2), source);
    BOOST_CHECK(addrman.size() == 2);

    // Test 6: AddrMan::Clear() should empty the new table.
    addrman.Clear();
    BOOST_CHECK(addrman.size() == 0);
    CAddrInfo addr_null2 = addrman.Select();
    BOOST_CHECK(addr_null2.ToString() == "[::]:0");
}

BOOST_AUTO_TEST_CASE(addrman_ports)
{
    CAddrManTest addrman;

    // Set addrman addr placement to be deterministic.
    addrman.MakeDeterministic();

    CNetAddr source = CNetAddr("252.2.2.2");

    BOOST_CHECK(addrman.size() == 0);

    // Test 7; Addr with same IP but diff port does not replace existing addr.
    CService addr1 = CService("250.1.1.1", 8333);
    addrman.Add(CAddress(addr1), source);
    BOOST_CHECK(addrman.size() == 1);

    CService addr1_port = CService("250.1.1.1", 8334);
    addrman.Add(CAddress(addr1_port), source);
    BOOST_CHECK(addrman.size() == 1);
    CAddrInfo addr_ret2 = addrman.Select();
    BOOST_CHECK(addr_ret2.ToString() == "250.1.1.1:8333");

    // Test 8: Add same IP but diff port to tried table, it doesn't get added.
    //  Perhaps this is not ideal behavior but it is the current behavior.
    addrman.Good(CAddress(addr1_port));
    BOOST_CHECK(addrman.size() == 1);
    bool newOnly = true;
    CAddrInfo addr_ret3 = addrman.Select(newOnly);
    BOOST_CHECK(addr_ret3.ToString() == "250.1.1.1:8333");
}

BOOST_AUTO_TEST_CASE(addrman_select)
{
    CAddrManTest addrman;

    // Set addrman addr placement to be deterministic.
    addrman.MakeDeterministic();

    CNetAddr source = CNetAddr("252.2.2.2");

    // Test 9: Select from new with 1 addr in new.
    CService addr1 = CService("250.1.1.1", 8333);
    addrman.Add(CAddress(addr1), source);
    BOOST_CHECK(addrman.size() == 1);

    bool newOnly = true;
    CAddrInfo addr_ret1 = addrman.Select(newOnly);
    BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333");

    // Test 10: move addr to tried, select from new expected nothing returned.
    addrman.Good(CAddress(addr1));
    BOOST_CHECK(addrman.size() == 1);
    CAddrInfo addr_ret2 = addrman.Select(newOnly);
    BOOST_CHECK(addr_ret2.ToString() == "[::]:0");

    CAddrInfo addr_ret3 = addrman.Select();
    BOOST_CHECK(addr_ret3.ToString() == "250.1.1.1:8333");

    BOOST_CHECK(addrman.size() == 1);

    // Add three addresses to new table.
    CService addr2 = CService("250.3.1.1", 8333);
    CService addr3 = CService("250.3.2.2", 9999);
    CService addr4 = CService("250.3.3.3", 9999);

    addrman.Add(CAddress(addr2), CService("250.3.1.1", 8333));
    addrman.Add(CAddress(addr3), CService("250.3.1.1", 8333));
    addrman.Add(CAddress(addr4), CService("250.4.1.1", 8333));

    // Add three addresses to tried table.
    CService addr5 = CService("250.4.4.4", 8333);
    CService addr6 = CService("250.4.5.5", 7777);
    CService addr7 = CService("250.4.6.6", 8333);

    addrman.Add(CAddress(addr5), CService("250.3.1.1", 8333));
    addrman.Good(CAddress(addr5));
    addrman.Add(CAddress(addr6), CService("250.3.1.1", 8333));
    addrman.Good(CAddress(addr6));
    addrman.Add(CAddress(addr7), CService("250.1.1.3", 8333));
    addrman.Good(CAddress(addr7));

    // Test 11: 6 addrs + 1 addr from last test = 7.
    BOOST_CHECK(addrman.size() == 7);

    // Test 12: Select pulls from new and tried regardless of port number.
    BOOST_CHECK(addrman.Select().ToString() == "250.4.6.6:8333");
    BOOST_CHECK(addrman.Select().ToString() == "250.3.2.2:9999");
    BOOST_CHECK(addrman.Select().ToString() == "250.3.3.3:9999");
    BOOST_CHECK(addrman.Select().ToString() == "250.4.4.4:8333");
}

BOOST_AUTO_TEST_CASE(addrman_new_collisions)
{
    CAddrManTest addrman;

    // Set addrman addr placement to be deterministic.
    addrman.MakeDeterministic();

    CNetAddr source = CNetAddr("252.2.2.2");

    BOOST_CHECK(addrman.size() == 0);

    for (unsigned int i = 1; i < 18; i++) {
        CService addr = CService("250.1.1." + std::to_string(i));
        addrman.Add(CAddress(addr), source);

        //Test 13: No collision in new table yet.
        BOOST_CHECK(addrman.size() == i);
    }

    //Test 14: new table collision!
    CService addr1 = CService("250.1.1.18");
    addrman.Add(CAddress(addr1), source);
    BOOST_CHECK(addrman.size() == 17);

    CService addr2 = CService("250.1.1.19");
    addrman.Add(CAddress(addr2), source);
    BOOST_CHECK(addrman.size() == 18);
}

BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
{
    CAddrManTest addrman;

    // Set addrman addr placement to be deterministic.
    addrman.MakeDeterministic();

    CNetAddr source = CNetAddr("252.2.2.2");

    BOOST_CHECK(addrman.size() == 0);

    for (unsigned int i = 1; i < 80; i++) {
        CService addr = CService("250.1.1." + std::to_string(i));
        addrman.Add(CAddress(addr), source);
        addrman.Good(CAddress(addr));

        //Test 15: No collision in tried table yet.
        BOOST_TEST_MESSAGE(addrman.size());
        BOOST_CHECK(addrman.size() == i);
    }

    //Test 16: tried table collision!
    CService addr1 = CService("250.1.1.80");
    addrman.Add(CAddress(addr1), source);
    BOOST_CHECK(addrman.size() == 79);

    CService addr2 = CService("250.1.1.81");
    addrman.Add(CAddress(addr2), source);
    BOOST_CHECK(addrman.size() == 80);
}

BOOST_AUTO_TEST_CASE(addrman_find)
{
    CAddrManTest addrman;

    // Set addrman addr placement to be deterministic.
    addrman.MakeDeterministic();

    BOOST_CHECK(addrman.size() == 0);

    CAddress addr1 = CAddress(CService("250.1.2.1", 8333));
    CAddress addr2 = CAddress(CService("250.1.2.1", 9999));
    CAddress addr3 = CAddress(CService("251.255.2.1", 8333));

    CNetAddr source1 = CNetAddr("250.1.2.1");
    CNetAddr source2 = CNetAddr("250.1.2.2");

    addrman.Add(addr1, source1);
    addrman.Add(addr2, source2);
    addrman.Add(addr3, source1);

    // Test 17: ensure Find returns an IP matching what we searched on.
    CAddrInfo* info1 = addrman.Find(addr1);
    BOOST_CHECK(info1);
    if (info1)
        BOOST_CHECK(info1->ToString() == "250.1.2.1:8333");

    // Test 18; Find does not discriminate by port number.
    CAddrInfo* info2 = addrman.Find(addr2);
    BOOST_CHECK(info2);
    if (info2)
        BOOST_CHECK(info2->ToString() == info1->ToString());

    // Test 19: Find returns another IP matching what we searched on.
    CAddrInfo* info3 = addrman.Find(addr3);
    BOOST_CHECK(info3);
    if (info3)
        BOOST_CHECK(info3->ToString() == "251.255.2.1:8333");
}

BOOST_AUTO_TEST_CASE(addrman_create)
{
    CAddrManTest addrman;

    // Set addrman addr placement to be deterministic.
    addrman.MakeDeterministic();

    BOOST_CHECK(addrman.size() == 0);

    CAddress addr1 = CAddress(CService("250.1.2.1", 8333));
    CNetAddr source1 = CNetAddr("250.1.2.1");

    int nId;
    CAddrInfo* pinfo = addrman.Create(addr1, source1, &nId);

    // Test 20: The result should be the same as the input addr.
    BOOST_CHECK(pinfo->ToString() == "250.1.2.1:8333");

    CAddrInfo* info2 = addrman.Find(addr1);
    BOOST_CHECK(info2->ToString() == "250.1.2.1:8333");
}

BOOST_AUTO_TEST_CASE(addrman_delete)
{
    CAddrManTest addrman;

    // Set addrman addr placement to be deterministic.
    addrman.MakeDeterministic();

    BOOST_CHECK(addrman.size() == 0);

    CAddress addr1 = CAddress(CService("250.1.2.1", 8333));
    CNetAddr source1 = CNetAddr("250.1.2.1");

    int nId;
    addrman.Create(addr1, source1, &nId);

    // Test 21: Delete should actually delete the addr.
    BOOST_CHECK(addrman.size() == 1);
    addrman.Delete(nId);
    BOOST_CHECK(addrman.size() == 0);
    CAddrInfo* info2 = addrman.Find(addr1);
    BOOST_CHECK(info2 == NULL);
}

BOOST_AUTO_TEST_CASE(addrman_getaddr)
{
    CAddrManTest addrman;

    // Set addrman addr placement to be deterministic.
    addrman.MakeDeterministic();

    // Test 22: Sanity check, GetAddr should never return anything if addrman
    //  is empty.
    BOOST_CHECK(addrman.size() == 0);
    vector<CAddress> vAddr1 = addrman.GetAddr();
    BOOST_CHECK(vAddr1.size() == 0);

    CAddress addr1 = CAddress(CService("250.250.2.1", 8333));
    addr1.nTime = GetAdjustedTime(); // Set time so isTerrible = false
    CAddress addr2 = CAddress(CService("250.251.2.2", 9999));
    addr2.nTime = GetAdjustedTime();
    CAddress addr3 = CAddress(CService("251.252.2.3", 8333));
    addr3.nTime = GetAdjustedTime();
    CAddress addr4 = CAddress(CService("252.253.3.4", 8333));
    addr4.nTime = GetAdjustedTime();
    CAddress addr5 = CAddress(CService("252.254.4.5", 8333));
    addr5.nTime = GetAdjustedTime();
    CNetAddr source1 = CNetAddr("250.1.2.1");
    CNetAddr source2 = CNetAddr("250.2.3.3");

    // Test 23: Ensure GetAddr works with new addresses.
    addrman.Add(addr1, source1);
    addrman.Add(addr2, source2);
    addrman.Add(addr3, source1);
    addrman.Add(addr4, source2);
    addrman.Add(addr5, source1);

    // GetAddr returns 23% of addresses, 23% of 5 is 1 rounded down.
    BOOST_CHECK(addrman.GetAddr().size() == 1);

    // Test 24: Ensure GetAddr works with new and tried addresses.
    addrman.Good(CAddress(addr1));
    addrman.Good(CAddress(addr2));
    BOOST_CHECK(addrman.GetAddr().size() == 1);

    // Test 25: Ensure GetAddr still returns 23% when addrman has many addrs.
    for (unsigned int i = 1; i < (8 * 256); i++) {
        int octet1 = i % 256;
        int octet2 = (i / 256) % 256;
        int octet3 = (i / (256 * 2)) % 256;
        string strAddr = std::to_string(octet1) + "." + std::to_string(octet2) + "." + std::to_string(octet3) + ".23";
        CAddress addr = CAddress(CService(strAddr));

        // Ensure that for all addrs in addrman, isTerrible == false.
        addr.nTime = GetAdjustedTime();
        addrman.Add(addr, CNetAddr(strAddr));
        if (i % 8 == 0)
            addrman.Good(addr);
    }
    vector<CAddress> vAddr = addrman.GetAddr();

    size_t percent23 = (addrman.size() * 23) / 100;
    BOOST_CHECK(vAddr.size() == percent23);
    BOOST_CHECK(vAddr.size() == 461);
    // (Addrman.size() < number of addresses added) due to address collisons.
    BOOST_CHECK(addrman.size() == 2007);
}

BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket)
{
    CAddrManTest addrman;

    // Set addrman addr placement to be deterministic.
    addrman.MakeDeterministic();

    CAddress addr1 = CAddress(CService("250.1.1.1", 8333));
    CAddress addr2 = CAddress(CService("250.1.1.1", 9999));

    CNetAddr source1 = CNetAddr("250.1.1.1");

    CAddrInfo info1 = CAddrInfo(addr1, source1);

    uint256 nKey1 = (uint256)(CHashWriter(SER_GETHASH, 0) << 1).GetHash();
    uint256 nKey2 = (uint256)(CHashWriter(SER_GETHASH, 0) << 2).GetHash();

    BOOST_CHECK(info1.GetTriedBucket(nKey1) == 40);

    // Test 26: Make sure key actually randomizes bucket placement. A fail on
    //  this test could be a security issue.
    BOOST_CHECK(info1.GetTriedBucket(nKey1) != info1.GetTriedBucket(nKey2));

    // Test 27: Two addresses with same IP but different ports can map to
    //  different buckets because they have different keys.
    CAddrInfo info2 = CAddrInfo(addr2, source1);

    BOOST_CHECK(info1.GetKey() != info2.GetKey());
    BOOST_CHECK(info1.GetTriedBucket(nKey1) != info2.GetTriedBucket(nKey1));

    set<int> buckets;
    for (int i = 0; i < 255; i++) {
        CAddrInfo infoi = CAddrInfo(
            CAddress(CService("250.1.1." + std::to_string(i))),
            CNetAddr("250.1.1." + std::to_string(i)));
        int bucket = infoi.GetTriedBucket(nKey1);
        buckets.insert(bucket);
    }
    // Test 28: IP addresses in the same group (\16 prefix for IPv4) should
    //  never get more than 8 buckets
    BOOST_CHECK(buckets.size() == 8);

    buckets.clear();
    for (int j = 0; j < 255; j++) {
        CAddrInfo infoj = CAddrInfo(
            CAddress(CService("250." + std::to_string(j) + ".1.1")),
            CNetAddr("250." + std::to_string(j) + ".1.1"));
        int bucket = infoj.GetTriedBucket(nKey1);
        buckets.insert(bucket);
    }
    // Test 29: IP addresses in the different groups should map to more than
    //  8 buckets.
    BOOST_CHECK(buckets.size() == 160);
}

BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
{
    CAddrManTest addrman;

    // Set addrman addr placement to be deterministic.
    addrman.MakeDeterministic();

    CAddress addr1 = CAddress(CService("250.1.2.1", 8333));
    CAddress addr2 = CAddress(CService("250.1.2.1", 9999));

    CNetAddr source1 = CNetAddr("250.1.2.1");

    CAddrInfo info1 = CAddrInfo(addr1, source1);

    uint256 nKey1 = (uint256)(CHashWriter(SER_GETHASH, 0) << 1).GetHash();
    uint256 nKey2 = (uint256)(CHashWriter(SER_GETHASH, 0) << 2).GetHash();

    BOOST_CHECK(info1.GetNewBucket(nKey1) == 786);

    // Test 30: Make sure key actually randomizes bucket placement. A fail on
    //  this test could be a security issue.
    BOOST_CHECK(info1.GetNewBucket(nKey1) != info1.GetNewBucket(nKey2));

    // Test 31: Ports should not effect bucket placement in the addr
    CAddrInfo info2 = CAddrInfo(addr2, source1);
    BOOST_CHECK(info1.GetKey() != info2.GetKey());
    BOOST_CHECK(info1.GetNewBucket(nKey1) == info2.GetNewBucket(nKey1));

    set<int> buckets;
    for (int i = 0; i < 255; i++) {
        CAddrInfo infoi = CAddrInfo(
            CAddress(CService("250.1.1." + std::to_string(i))),
            CNetAddr("250.1.1." + std::to_string(i)));
        int bucket = infoi.GetNewBucket(nKey1);
        buckets.insert(bucket);
    }
    // Test 32: IP addresses in the same group (\16 prefix for IPv4) should
    //  always map to the same bucket.
    BOOST_CHECK(buckets.size() == 1);

    buckets.clear();
    for (int j = 0; j < 4 * 255; j++) {
        CAddrInfo infoj = CAddrInfo(CAddress(
                                        CService(
                                            std::to_string(250 + (j / 255)) + "." + std::to_string(j % 256) + ".1.1")),
            CNetAddr("251.4.1.1"));
        int bucket = infoj.GetNewBucket(nKey1);
        buckets.insert(bucket);
    }
    // Test 33: IP addresses in the same source groups should map to no more
    //  than 64 buckets.
    BOOST_CHECK(buckets.size() <= 64);

    buckets.clear();
    for (int p = 0; p < 255; p++) {
        CAddrInfo infoj = CAddrInfo(
            CAddress(CService("250.1.1.1")),
            CNetAddr("250." + std::to_string(p) + ".1.1"));
        int bucket = infoj.GetNewBucket(nKey1);
        buckets.insert(bucket);
    }
    // Test 34: IP addresses in the different source groups should map to more
    //  than 64 buckets.
    BOOST_CHECK(buckets.size() > 64);
}

BOOST_AUTO_TEST_CASE(addrman_selecttriedcollision)
{
    CAddrManTest addrman;

    // Set addrman addr placement to be deterministic.
    addrman.MakeDeterministic();

    BOOST_CHECK(addrman.size() == 0);

    // Empty addrman should return blank addrman info.
    BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");

    // Add twenty two addresses.
    CNetAddr source = CNetAddr("252.2.2.2");
    for (unsigned int i = 1; i < 23; i++) {
        CService addr =CService("250.1.1."+std::to_string(i));
        addrman.Add(CAddress(addr), source);
        addrman.Good(addr);

        // No collisions yet.
        BOOST_CHECK(addrman.size() == i);
        BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
    }

    // Ensure Good handles duplicates well.
    for (unsigned int i = 1; i < 23; i++) {
        CService addr = CService("250.1.1."+std::to_string(i));
        addrman.Good(addr);

        BOOST_CHECK(addrman.size() == 22);
        BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
    }

}

BOOST_AUTO_TEST_CASE(addrman_noevict)
{
    CAddrManTest addrman;

    // Set addrman addr placement to be deterministic.
    addrman.MakeDeterministic();

    // Add twenty two addresses.
    CNetAddr source = CNetAddr("252.2.2.2");
    for (unsigned int i = 1; i < 23; i++) {
        CService addr = CService("250.1.1."+std::to_string(i));
        addrman.Add(CAddress(addr), source);
        addrman.Good(addr);

        // No collision yet.
        BOOST_CHECK(addrman.size() == i);
        BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
    }

    // Collision between 23 and 19.
    CService addr23 = CService("250.1.1.23");
    addrman.Add(CAddress(addr23), source);
    addrman.Good(addr23);

    BOOST_CHECK(addrman.size() == 23);
    BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "250.1.1.19:0");

    // 23 should be discarded and 19 not evicted.
    addrman.ResolveCollisions();
    BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");

    // Lets create two collisions.
    for (unsigned int i = 24; i < 33; i++) {
        CService addr = CService("250.1.1."+std::to_string(i));
        addrman.Add(CAddress(addr), source);
        addrman.Good(addr);

        BOOST_CHECK(addrman.size() == i);
        BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
    }

    // Cause a collision.
    CService addr33 = CService("250.1.1.33");
    addrman.Add(CAddress(addr33), source);
    addrman.Good(addr33);
    BOOST_CHECK(addrman.size() == 33);

    BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "250.1.1.27:0");

    // Cause a second collision.
    addrman.Add(CAddress(addr23), source);
    addrman.Good(addr23);
    BOOST_CHECK(addrman.size() == 33);

    BOOST_CHECK(addrman.SelectTriedCollision().ToString() != "[::]:0");
    addrman.ResolveCollisions();
    BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
}

BOOST_AUTO_TEST_CASE(addrman_evictionworks)
{
    CAddrManTest addrman;

    // Set addrman addr placement to be deterministic.
    addrman.MakeDeterministic();

    BOOST_CHECK(addrman.size() == 0);

    // Empty addrman should return blank addrman info.
    BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");

    // Add twenty two addresses.
    CNetAddr source = CNetAddr("252.2.2.2");
    for (unsigned int i = 1; i < 23; i++) {
        CService addr = CService("250.1.1."+std::to_string(i));
        addrman.Add(CAddress(addr), source);
        addrman.Good(addr);

        // No collision yet.
        BOOST_CHECK(addrman.size() == i);
        BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
    }

    // Collision between 23 and 19.
    CService addr = CService("250.1.1.23");
    addrman.Add(CAddress(addr), source);
    addrman.Good(addr);

    BOOST_CHECK(addrman.size() == 23);
    CAddrInfo info = addrman.SelectTriedCollision();
    BOOST_CHECK(info.ToString() == "250.1.1.19:0");

    // Ensure test of address fails, so that it is evicted.
    addrman.SimConnFail(info);

    // Should swap 23 for 19.
    addrman.ResolveCollisions();
    BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");

    // If 23 was swapped for 19, then this should cause no collisions.
    addrman.Add(CAddress(addr), source);
    addrman.Good(addr);

    BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");

    // If we insert 19 is should collide with 23.
    CService addr19 = CService("250.1.1.19");
    addrman.Add(CAddress(addr19), source);
    addrman.Good(addr19);

    BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "250.1.1.23:0");

    addrman.ResolveCollisions();
    BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
}

BOOST_AUTO_TEST_SUITE_END()


text:
package hu.vitamas.enotesz.util;

/**
 * Validating registration form with chaining.
 *
 * @author vitozy
 *
 */
public class RegistrationFormValidator {
	private Boolean valid;

	private RegistrationFormValidator(){
		valid = true;
	}

	/**
	 * Returns with new validator instance.
	 *
	 * @return instance
	 */
	public static RegistrationFormValidator newValidator(){
		return new RegistrationFormValidator();
	}

	/**
	 * Checks the name. If not okay then set valid flag to false.
	 *
	 *
Server API checks it is unique or not.
	 *
	 * @param name user's name
	 * @return RegistrationFormValidator
	 */
	public RegistrationFormValidator checkName(String name){
		if(name.length() == 0) valid = false;
		return this;
	}

	/**
	 * Checks email. If not okay then set valid flag to false.
	 *
	 *
Server API checks it is unique and valid e-mail or not.
	 *
	 * @param email e-mail address
	 * @return RegistrationFormValidator
	 */
	public RegistrationFormValidator checkEmail(String email){
		if (email.length() == 0) valid = false;
		return this;
	}

	/**
	 * Checks passwords. If not okay then set valid flag to false.
	 *
	 * @param pass password
	 * @param repass password again
	 * @return RegistrationFormValidator
	 */
	public RegistrationFormValidator checkPasswords(String pass, String repass){
		if (pass.length() < 8 || repass.length() < 8 || !pass.equals(repass))
			valid = false;
		return this;
	}

	/**
	 * It is valid or not.
	 *
	 * @return valid or not
	 */
	public Boolean isValid(){
		return valid;
	}
}

redpajama_set_name: RedPajamaGithub


text:
layout: post
title: "Java Annotation Inheritance"
description: ""
cover: cover.jpg
category:
tags: [java,reflection]
---

I ran into an issue recently with Java, where I had two classes, one extending from the other, and an annotation attached to the super class.

I was using reflection to detect the annotation, but it was returning false!  Here is my findings, and my solution to:

> How can your subclasses inherit the super classes annotations?

## Answer is: `java.lang.Inherited`

```java
public class Main {
    public static void main(String ... args) {
        A a = new A();
        B b = new B();
        System.out.println(a.getClass().isAnnotationPresent(Annotation.class));
        System.out.println(b.getClass().isAnnotationPresent(Annotation.class));
    }
}

@Annotation
class A {}
class B extends A {}

@Retention(RetentionPolicy.RUNTIME)
@Inherited // <- here's the key!
@interface Annotation {}
```

### Console Output:

```java
true
true
```

If you take out `@Inherited` the result would be:

### Console Output:

```java
true
false
```


text:
from .model import KineticsModel, PDepKineticsModel, TunnelingModel, \
                   getRateCoefficientUnitsFromReactionOrder, getReactionOrderFromRateCoefficientUnits
from .arrhenius import Arrhenius, ArrheniusEP, PDepArrhenius, MultiArrhenius, MultiPDepArrhenius
from .chebyshev import Chebyshev
from .falloff import ThirdBody, Lindemann, Troe
from .kineticsdata import KineticsData, PDepKineticsData
from .tunneling import Wigner, Eckart


text:
package org.apache.amber.oauth2.rs.extractor;

import javax.servlet.http.HttpServletRequest;

import junit.framework.Assert;

import org.apache.amber.oauth2.common.OAuth;
import org.apache.amber.oauth2.rs.extractor.BearerHeaderTokenExtractor;
import org.junit.Test;

import static org.easymock.EasyMock.createStrictMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;

/**
 *
 *
 *
 */
public class HeaderTokenExtractorTest {

    @Test
    public void testGetAccessToken() throws Exception {

        HttpServletRequest request = createStrictMock(HttpServletRequest.class);
        expect(request.getHeader(OAuth.HeaderType.AUTHORIZATION)).andStubReturn("Bearer sometoken");
        replay(request);
        BearerHeaderTokenExtractor hte = new BearerHeaderTokenExtractor();
        Assert.assertEquals("sometoken", hte.getAccessToken(request));
        verify(request);
    }

    @Test
    public void testGetAccessTokenNull() throws Exception {

        HttpServletRequest request = createStrictMock(HttpServletRequest.class);
        expect(request.getHeader(OAuth.HeaderType.AUTHORIZATION)).andStubReturn(null);
        replay(request);
        BearerHeaderTokenExtractor hte = new BearerHeaderTokenExtractor();
        Assert.assertNull(hte.getAccessToken(request));
        verify(request);
    }
}


text:
export default class RssFeedParser {

  constructor(sourceKey: string) {
    this.sourceKey = sourceKey;
  }

  parse(content: string) {
    throw new Error('parse(sourceKey: string, content: string) method should be implemented in child class.');
  }

}


text:
package com.rvprg.sumi.protocol;

import com.rvprg.sumi.configuration.Configuration;
import com.rvprg.sumi.log.Log;
import com.rvprg.sumi.transport.MemberId;
import com.rvprg.sumi.transport.MemberIdentifiable;

public interface Consensus extends MessageConsumer, MemberIdentifiable {
    void start() throws InterruptedException;

    void shutdown() throws InterruptedException;

    boolean isStarted();

    int getCurrentTerm();

    MemberRole getRole();

    Configuration getConfiguration();

    Log getLog();

    ApplyCommandResult applyCommand(byte[] command);

    ApplyCommandResult addMemberDynamically(MemberId memberId);

    ApplyCommandResult removeMemberDynamically(MemberId memberId);

    AddCatchingUpMemberResult addCatchingUpMember(MemberId memberId);

    RemoveCatchingUpMemberResult removeCatchingUpMember(MemberId memberId);

    boolean isVotingMember();

    boolean isCatchingUpMember();

    void becomeCatchingUpMember();

    void becomeVotingMember();
}


text:
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/entries', __FILE__)

describe "Enumerable#entries" do
  it_behaves_like(:enumerable_entries , :entries)
end


text:
from typing import List, Optional

from lxml import etree

MARKUP = u'**{}**'

class Word:
    """
    Each Word consists of a word, its lemma, and a designation if this is part of a construction.
    """
    def __init__(self, word: str, lemma: str, pos: str, xml_id: str,
                 in_construction: bool = True) -> None:
        self.word = word.strip()
        self.lemma = lemma.strip()
        self.pos = pos.strip()
        self.xml_id = xml_id.strip()
        self.in_construction = in_construction

class MultiWordExpression:
    def __init__(self, xml_sentence: etree._Element) -> None:
        self.xml_sentence = xml_sentence
        self.words: List[Word] = []

    def add_word(self, word: str, lemma: str, pos: str, xml_id: str,
                 in_construction: bool = True) -> None:
        """
        Adds a word to the MultiWordExpression.
        """
        self.words.append(Word(word, lemma, pos, xml_id, in_construction))

    def prepend_word(self, word: str, lemma: str, pos: str, xml_id: str,
                     in_construction: bool = True) -> None:
        """
        Prepends a word to the MultiWordExpression.
        """
        self.words.insert(0, Word(word, lemma, pos, xml_id, in_construction))

    def construction(self) -> List[str]:
        """
        Extracts the words in the construction from the MultiWordExpression.
        """
        return [w.word for w in self.words if w.in_construction]

    def construction_to_string(self) -> str:
        """
        Returns the construction from the MultiWordExpression as a string.
        """
        return ' '.join(self.construction())

    def construction_ids(self) -> str:
        return ' '.join([w.xml_id for w in self.words if w.in_construction])

    def words_between(self) -> int:
        """
        Returns the total number of words in a MultiWordExpression not of part of the construction.
        """
        return len([w.word for w in self.words if not w.in_construction])

    def words_between_construction(self) -> List[int]:
        """
        Returns the number of words in a MultiWordExpression between the construction.
        """
        result = []
        current_count = 0
        for w in self.words:
            if w.in_construction:
                result.append(current_count)
                current_count = 0
            else:
                current_count += 1

        return result

    def get_sentence_words(self) -> str:
        s = []
        # TODO: this xPath-expression might be specific for a corpus
        if self.xml_sentence is not None:
            words: List[etree._Element] = self.xml_sentence.xpath('.//w')
            for w in words:
                s.append(str(w.text.strip() if w.text else ' '))
        return ' '.join(s)

    def mark_sentence(self) -> str:
        """
        Marks the MultiWordExpression in a full sentence.
        """
        # TODO: this doesn't work if no xml_sentence is given
        if self.xml_sentence is None:
            return ''

        # TODO: this is a bit iffy, another idea could be to compose the sentence from the remaining siblings
        # To find the pp in the full text, simply join all the parts of the pp
        pp_text = ' '.join([w.word for w in self.words])

        # For the replacement, mark the verbs with the MARKUP
        if len(self.words) == len(self.construction()):
            marked_pp = MARKUP.format(pp_text)
        else:
            marked_pp = ' '.join([MARKUP.format(w.word) if w.in_construction else w.word for w in self.words])

        return self.get_sentence_words().replace(pp_text, marked_pp)

class Perfect(MultiWordExpression):
    """
    A Perfect is a special kind of MultiWordExpression, consisting of an auxiliary and one or more past participles.
    """

    def __init__(self, xml_sentence: etree._Element) -> None:
        super().__init__(xml_sentence)
        self.is_passive = False
        self.is_continuous = False
        self.is_reflexive = False

    def extend(self, perfect: 'Perfect') -> None:
        """
        Extends a Perfect with another one (used to create a passive or continuous Perfect).
        """
        for i, w in enumerate(perfect.words):
            if i == 0:
                continue
            self.add_word(w.word, w.lemma, w.pos, w.xml_id, w.in_construction)

        self.is_passive = not perfect.is_continuous
        self.is_continuous = perfect.is_continuous

    def perfect_lemma(self) -> str:
        """
        Returns the lemma of the Perfect: the lemma of the last word of the construction.
        """
        return self.words[-1].lemma

    def perfect_type(self) -> str:
        """
        Returns the type of Perfect.
        """
        # TODO: This should be language-dependent, as well as dependent upon being a Present or Past Perfect
        result = 'present perfect'
        if self.is_passive:
            result += ' passive'
        if self.is_continuous:
            result += ' continuous'
        return result

class Alignment:
    def __init__(self, sources: List[str], targets: List[str], certainty: Optional[float] = None) -> None:
        self.sources = sources
        self.targets = targets
        self.certainty = certainty


text:
	Clean up the decals
-----------------------------------------------------------------------------------------------------------------------]]--

local PLUGIN = {}
PLUGIN.Title = "Decals"
PLUGIN.Description = "Remove all decals from the map."
PLUGIN.Author = "Overv"
PLUGIN.ChatCommand = "decals"
PLUGIN.Privileges = { "Decal cleanup" }

function PLUGIN:Call( ply, args )
	if ( ply:EV_HasPrivilege( "Decal cleanup" ) ) then
		evolve:Notify( evolve.colors.blue, ply:Nick(), evolve.colors.white, " has cleaned up the decals." )

		for _, pl in ipairs( player.GetAll() ) do
			pl:ConCommand( "r_cleardecals" )
			pl:ConCommand( "r_cleardecals" )
		end
	else
		evolve:Notify( ply, evolve.colors.red, evolve.constants.notallowed )
	end
end

evolve:RegisterPlugin( PLUGIN )


text:
<?php

namespace Google\AdsApi\Dfp\v201705;

/**
 * This file was generated from WSDL. DO NOT EDIT.
 */
abstract class RedirectAsset extends \Google\AdsApi\Dfp\v201705\Asset
{

    /**
     * @var string $redirectUrl
     */
    protected $redirectUrl = null;

    /**
     * @param string $redirectUrl
     */
    public function __construct($redirectUrl = null)
    {
      $this->redirectUrl = $redirectUrl;
    }

    /**
     * @return string
     */
    public function getRedirectUrl()
    {
      return $this->redirectUrl;
    }

    /**
     * @param string $redirectUrl
     * @return \Google\AdsApi\Dfp\v201705\RedirectAsset
     */
    public function setRedirectUrl($redirectUrl)
    {
      $this->redirectUrl = $redirectUrl;
      return $this;
    }

}


text:
using System;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Haumea.Rendering;

namespace Haumea.Components
{
    /// <summary>
    /// The goal of this class is to draw a "minimap", a map which show a small version of the world,
    /// with the players current view port indicated.
    /// The code right now is very basic, and is mostly meant as a proof-of-concept.
    /// </summary>
    public class MiniMap : IView
    {
        private readonly MapView _mapView;
        private bool _initialized;
        private int _wait = 3;

        private RenderTarget2D _renderTarget;

        public MiniMap(MapView mapView)
        {
            _mapView = mapView;
            _initialized = false;
        }

        public void LoadContent(ContentManager content)
        {

        }

        public void Update(InputState input)
        {

        }

        public void Draw(SpriteBatch spriteBatch, Renderer renderer)
        {
            Vector2 portOffset = renderer.RenderState.Camera.Offset;

            Vector2 screen = spriteBatch.GetScreenDimensions();
            const int size = 200;
            float xyratio = screen.X / screen.Y;
            Vector2 dim = new Vector2(size * xyratio, size);

            if (!_initialized && _wait-- == 0) CreateMapTexture(renderer);

            if (_initialized)
            {
                const int offset = 120;
                Rectangle target = new Rectangle((screen - dim).ToPoint(), dim.ToPoint());
                Rectangle source = new Rectangle((int)(offset * xyratio), offset,
                    (int)(screen.X - offset * xyratio), (int)screen.Y - offset);
                spriteBatch.Draw(_renderTarget, target, source, Color.White);
            }

            Debug.WriteToScreen("wait", _wait);
        }

        private void CreateMapTexture(Renderer renderer)
        {
            var offset = new Vector2(20, 20);

            _renderTarget = new RenderTarget2D(
                renderer.Device,
                renderer.Device.PresentationParameters.BackBufferWidth,
                renderer.Device.PresentationParameters.BackBufferHeight,
                false,
                renderer.Device.PresentationParameters.BackBufferFormat,
                DepthFormat.Depth24);
            // Set the render target
            renderer.Device.SetRenderTarget(_renderTarget);

            var oldZoom = renderer.RenderState.Camera.Zoom;
            renderer.RenderState.Camera.Move(offset);
            renderer.RenderState.Camera.SetZoom(1.15f);

            renderer.Device.DepthStencilState = new DepthStencilState() { DepthBufferEnable = true };

            // Draw the scene
            renderer.Device.Clear(Color.CornflowerBlue);
            renderer.DrawToScreen(_mapView.RenderInstructons.SelectMany(x => x));

            // Restore
            renderer.Device.SetRenderTarget(null);
            renderer.RenderState.Camera.SetZoom(oldZoom);
            renderer.RenderState.Camera.Move(-offset);
            _initialized = true;
        }
    }
}


text:
(function(angular, $, global){

  global.app = angular.module('app', ['ui.router']);

  app.config(['$stateProvider' , '$urlRouterProvider','$locationProvider',function($stateProvider , $urlRouterProvider, $locationProvider) {

      $urlRouterProvider
        .rule(function ($injector, $location) {
          var path = $location.path(),
              normalized = path.toLowerCase();
          if (path !== normalized) {
            return normalized;
          }
        })
        .otherwise('/');

      $stateProvider

      .state('404',{
        url:'/404',
        templateUrl:'views/404.html',
        controller: ['$scope','$rootScope', '$state',function($scope,$rootScope, $state){
          var vm = this;
          $rootScope.$emit('changeTitleAppbar', '404 Error' );
          $rootScope.$emit('changeAppbar', 'default' );
          $rootScope.$emit('hideAction');
        }],
        controllerAs:'vm'
      })

      .state('home',{
        url:'/',
        //templateUrl:'views/home.html',
        controller:['$scope', '$verge',function($scope, $verge){
          console.log($verge.viewportW() );
          if ( $verge.viewportW() <= 768 ) { //Mobile

          }else{
            /**background **/
            $.backstretch([
              "assets/images/background/pollo-a-la-parrilla.jpg",
              "assets/images/background/chuleta.jpg",
              "assets/images/background/parrilla.jpg",
              "assets/images/background/pollo-a-la-brasa.jpg"
            ], {duration: 5000, fade: 750});
          };
        }],
        controllerAs:'vm'
      })

      .state('carta',{
        abstract: true,
        url:'/carta',
        templateUrl:'app/js/carta/index.html'
      })

      .state('carta.list',{
        url:'',
        views:{
          'list':{
            templateUrl:'app/js/carta/list.html',
            controller:['$scope',function($scope){
              console.log("list");
              $scope.title= 'Carta';
              $scope.carta=[
                {
                  name: 'Pollos a la brasa',
                  photo: 'pollobrasa1.jpg',
                  img:{'background-image':'url(images/portadas/standar/pollobrasa1.jpg)'} ,
                  plates: [
                    {
                      name: '1/4 Pollo a la Brasa ',
                      nameId:'1-4-pollo-a-la-brasa',

                      bg:{'background-image':'url(images/platos/square/pollo-brasa/cuarto/cuarto-pollo-a-la-brasa-1.jpg)'} ,
                      photo:'pollo-brasa/cuarto/cuarto-pollo-a-la-brasa-1.jpg',

                      description: '(Acompañado con crocantes papas fritas y ensalada clásica)',
                      price: 11
                    },
                    {
                      name: '1/2 Pollo a la Brasa ',
                      nameId:'1-2-pollo-a-la-brasa',
                      photo:'pollo-brasa/medio/medio-pollo-a-la-brasa-1.jpg',
                      bg:{'background-image':'url(images/platos/square/pollo-brasa/medio/medio-pollo-a-la-brasa-1.jpg)'} ,
                      description: '(Acompañado con crocantes papas fritas y ensalada clásica)',
                      price: 20
                    },
                    {
                      name: '1 Pollo a la Brasa ',
                      nameId:'1-pollo-a-la-brasa',
                      photo:'pollo-brasa/entero/entero-pollo-a-la-brasa-1.jpg',
                      bg:{'background-image':'url(images/platos/square/pollo-brasa/entero/entero-pollo-a-la-brasa-1.jpg)'} ,
                      description: '(Acompañado con crocantes papas fritas y ensalada clásica)',
                      price: 38
                    },
                    {
                      name: '1 Pollo a la Brasa (Delivery)',
                      nameId:'1-pollo-a-la-brasa-delivery',
                      photo:'pollo-brasa/delivery/pollo-a-la-brasa-delivery.jpg',
                      bg:{'background-image':'url(images/platos/square/pollo-brasa/delivery/pollo-a-la-brasa-delivery.jpg)'} ,
                      description: '(Acompañado con crocantes papas fritas y ensalada clásica)',
                      price: 40
                    }
                  ]
                },
                {
                  name: 'Pollo broaster',
                  photo: 'broaster1.jpg' ,
                  img:{'background-image':'url(images/portadas/standar/broaster1.jpg)'} ,
                    plates: [
                    {
                      name: '1/4 Pollo a la Broaster ',
                      nameId:'cuarto-pollo-broaster',
                      bg:{'background-image':'url(images/platos/square/pollo-broaster/cuarto/cuarto-pollo-broaster.jpg)'} ,
                      photo:'pollo-broaster/cuarto/cuarto-pollo-broaster.jpg',
                      description: '(Acompañado con crocantes papas fritas y ensalada clásica)',
                      price: 12
                    },
                    {
                      name: '1/2 Pollo a la Broaster ',
                      nameId:'medio-pollo-broaster',
                      bg:{'background-image':'url(images/platos/square/pollo-broaster/medio/pollo-broaster-medio.jpg)'} ,
                      photo:'pollo-broaster/medio/pollo-broaster-medio.jpg',
                      description: '(Acompañado con crocantes papas fritas y ensalada clásica)',
                      price: 22
                    },
                    {
                      name: '1 Pollo a la Broaster ',
                      nameId:'entero-pollo-a-la-brasa',
                      bg:{'background-image':'url(images/platos/square/pollo-broaster/entero/pollo-broaster-entero.jpg)'} ,
                      photo:'pollo-broaster/entero/pollo-broaster-entero.jpg',
                      description: '(Acompañado con crocantes papas fritas y ensalada clásica)',
                      price: 40
                    },
                    /*
                    {
                      name: "1/4 Pollo tedhi's",
                      nameId:'cuarto-pollo-broaster',
                      bg:{'background-image':'url(images/platos/square/pollo-broaster/cuarto/pollo-braster-cuarto.png)'} ,
                      photo:'pollo-broaster/cuarto/pollo-braster-cuarto.png',
                      subname: "(filete de pollo a la parrilla)" ,
                      description: '(Acompañado con crocantes papas fritas y ensalada clásica)',
                      price: 17
                    },
                    */
                    {
                      name: 'Alitas Broaster',
                      nameId:'alitas-broaster',
                      bg:{'background-image':'url(images/platos/square/alitas-broaster/alitas-broaster.jpg)'} ,
                      photo:'alitas-broaster/alitas-broaster.jpg',
                      description: '(Acompañado con crocantes papas fritas y ensalada clásica)',
                      price: 10
                    }
                  ]
                },
                {
                  name: 'Carnes',
                  photo: 'res1.jpg' ,
                  img:{'background-image':'url(images/portadas/standar/res1.jpg)'}
                  ,plates: [
                    {
                      name: ' Costillas de cerdo a lo Tedhi's ',
                      nameId:'costilla-de-cerdo',
                      //costillas-cerdo-tedhis
                      bg:{'background-image':'url(images/platos/square/costillas-cerdo-tedhis/costillas-de-cerdo-tedhis.jpg)'} ,
                      photo:'costillas-cerdo-tedhis/costillas-de-cerdo-tedhis.jpg',
                      description: '(3 deliciosas costillitas bañadas en una suave y colorida crema a la bbq, acompañadas con crocantes papas fritas y ensalada clásica)',
                      price: 17
                    },
                    {
                      name: ' Lomo Fino ',
                      nameId:'lomo-fino',
                      bg:{'background-image':'url(images/platos/square/lomo-fino/lomo-fino.jpg)'} ,
                      photo:'lomo-fino/lomo-fino.jpg',
                      description: ' (Un jugoso Lomo Fino adornado con chorizo, acompañado con crocantes papas fritas y ensalada clásica ) ',
                      price: 25
                    },
                    {
                      name: ' Lomo Fino con champiñones ',
                      nameId:'lomo-fino-con-champinones',
                      bg:{'background-image':'url(images/platos/square/lomo-fino-con-champinones/lomo-fino-con-champinones.jpg)'} ,
                      photo:'lomo-fino-con-champinones/lomo-fino-con-champinones.jpg',
                      description: ' (Un jugoso Lomo Fino con unos deliciosos y pequeños trozos de champiñones, acompañado con crocantes papas fritas y ensalada clásica) ',
                      price: 28
                    },
                    {
                      name: ' Lomo a la Visantina ',

                      description: ' (Un jugoso lomo cubierto por unas rodajas de jamón, queso y bañado en mostaza, acompañado con crocantes papas fritas y ensalada clásica) ',
                      price: 28
                    },
                    {
                      name: ' Churrasco a la parrilla ',
                      nameId:'churrasco-a-la-parrilla',
                      bg:{'background-image':'url(images/platos/square/churrasco-a-la-parrilla/churrasco-a-la-parrilla.jpg)'} ,
                      photo:'churrasco-a-la-parrilla/churrasco-a-la-parrilla.jpg',
                      description: ' (Un delicioso Churrasco recién salido de la parrilla, acompañado con crocantes papas fritas y ensalada clásica) ',
                      price: 17
                    }

                  ]
                },
                {
                  name: 'Piqueos',
                  photo: 'piqueos1.jpg' ,
                  img:{'background-image':'url(images/portadas/standar/piqueos1.jpg)'}
                  ,plates: [
                    {
                      name: ' Anticuchos de Corazón',
                      nameId:'anticucho-de-corazon',
                      bg:{'background-image':'url(images/platos/square/anticucho-de-corazon/anticucho-de-corazon.jpg)'} ,
                      photo:'anticucho-de-corazon/anticucho-de-corazon.jpg',
                      description: '(Unos deliciosos y jugosos Anticuchos, acompañados con crocantes papas fritas y ensalada clásica)',
                      price: 17
                    },{
                      name: ' Mollejitas a la parrilla ',
                      nameId:'mollejitas-a-la-parrilla',
                      bg:{'background-image':'url(images/platos/square/mollejitas-a-la-parrilla/mollejitas-a-la-parrilla.jpg)'} ,
                      photo:'mollejitas-a-la-parrilla/mollejitas-a-la-parrilla.jpg',
                      description: '(Unas deliciosas Mollejitas recién salidas de la parrilla, acompañadas con crocantes papas fritas y ensalada clásica)',
                      price: 15
                    },{
                      name: ' Brochetas de pollo ',
                      nameId:'brochetas-de-pollo',
                      bg:{'background-image':'url(images/platos/square/brochetas-de-pollo/brochetas-de-pollo.jpg)'} ,
                      photo:'brochetas-de-pollo/brochetas-de-pollo.jpg',
                      description: '(Unas Brochetas de pollo, unos coloridos trozos de pimiento y cebolla, acompañados con crocantes papas fritas y ensalada clásica)',
                      price: 17
                    },{
                      name: ' chicharron de pollo',
                      nameId:'chicharron-de-pollo',
                      bg:{'background-image':'url(images/platos/square/chicharron-de-pollo/chicharron-de-pollo.jpg)'} ,
                      photo:'chicharron-de-pollo/chicharron-de-pollo.jpg',
                      description: '(Crocantes trozos de pollo, acompañados con deliciosas papas fritas y ensalada clásica)',
                      price: 17
                    },{
                      name: ' Marucha',
                      nameId:'marucha',
                      bg:{'background-image':'url(images/platos/square/marucha/marucha.jpg)'} ,
                      photo:'marucha/marucha.jpg',
                      description: 'Un filete de carne, acompañada con crocantes papas fritas y ensalada clásica',
                      price: 17
                    },{
                      name: ' Chuleta ',
                      nameId:'chuleta',
                      bg:{'background-image':'url(images/platos/square/chuleta/chuleta.jpg)'} ,
                      photo:'chuleta/chuleta.jpg',
                      description: 'Una jugosa chuleta a la parrilla, acompañada con crocantes papas fritas y ensalada clásica',
                      price: 17
                    },{
                      name: ' Chorizo ',
                      nameId:'chorizo',
                      bg:{'background-image':'url(images/platos/square/chorizo/chorizo.jpg)'} ,
                      photo:'chorizo/chorizo.jpg',
                      description: 'Tres deliciosos chorizo a la parrilla, acompañados con crocantes papas fritas y ensalada clásica',
                      price: 15
                    },{
                      name: ' Bisteck a la parrilla ',
                      nameId:'bisteck-a-la-parrilla',
                      bg:{'background-image':'url(images/platos/square/bisteck-a-la-parrilla/bisteck-a-la-parrilla.jpg)'} ,
                      photo:'bisteck-a-la-parrilla/bisteck-a-la-parrilla.jpg',
                      description: 'Un jugoso Bisteck a la parrilla, acompañado con crocantes papas fritas y ensalada clásica',
                      price: 17
                    },{
                      name: ' Lengua de res a la parrilla ',
                      nameId:'lengua-a-la-parrilla',
                      bg:{'background-image':'url(images/platos/square/lengua-a-la-parrilla/lengua-a-la-parrilla.jpg)'} ,
                      photo:'lengua-a-la-parrilla/lengua-a-la-parrilla.jpg',
                      description: 'Una jugosa Lengua a la parrilla, acompañado con crocantes papas fritas y ensalada clásica',
                      price: 17
                    }
                  ]
                },
                {
                  name: 'Parrilla',
                  photo: 'parrilla1.jpg' ,
                  img:{'background-image':'url(images/portadas/standar/parrilla1.jpg)'}
                  ,plates: [
                    {
                      name: ' Piqueo Tedhi's  ',
                      nameId:'piqueo-tedhis-entero',
                      bg:{'background-image':'url(images/platos/square/piqueos-tedhis/entero/piqueo-tedhis-entero.jpg)'} ,
                      photo:'piqueos-tedhis/entero/piqueo-tedhis-entero.jpg',
                      subname: '(4 personas) ',
                      description: '4 Palitos de anticuchos, 4 Palitos de brochetas, 8 Trozos de chicharron, 6 Mollejitas con papas fritas y ensalada ',
                      price: 50
                    },{
                      name: ' 1/2 Piqueo Tedhi's   ',
                      nameId:'piqueo-tedhis-medio',
                      bg:{'background-image':'url(images/platos/square/piqueos-tedhis/medio/piqueo-tedhis-medio.jpg)'} ,
                      photo:'piqueos-tedhis/medio/piqueo-tedhis-medio.jpg',
                      subname: '(2 personas) ',
                      description: ' 2 Palitos de anticuchos, 2 Palitos de brochetas, 4 Trozos de chicharron,4 Mollejitas con papas fritas y ensalada  ',
                      price: 27
                    },
                    {
                      name: ' Parrilla Mixta   ',
                      nameId:'parilla-mixta',
                      bg:{'background-image':'url(images/platos/square/parilla-mixta/parilla-mixta.jpg)'} ,
                      photo:'parilla-mixta/parilla-mixta.jpg',
                      subname: '(4 personas) ',
                      description: ' Marucha, Chorizo, Filete de Pollo, Chuletas con papas fritas y ensalada  ',
                      price: 50
                    },
                    {
                      name: ' Parrillada Tedhi's   ',
                      nameId:'parrilla-tedhis',
                      bg:{'background-image':'url(images/platos/square/parrilla-tedhis/parrilla-tedhis.jpg)'} ,
                      photo:'parrilla-tedhis/parrilla-tedhis.jpg',
                      subname: '(6 personas) ',
                      description: ' Lomo Fino, Filete de Pollo, 3 Costillas de cerdo, 3 Lenguas, Chorizos, 3 Palitos de corazón con papas fritas y ensalada  ',
                      price: 80
                    },
                  ]
                },
                {
                  name: 'Ensaladas',
                  photo: 'ensalada1.jpg' ,
                  img:{'background-image':'url(images/portadas/standar/ensalada1.jpg)'}
                  ,plates: [
                    {
                      name: ' Ensalada Clásica  ',
                      nameId:'ensalada-clasica',
                      bg:{'background-image':'url(images/platos/square/ensaladas/clasica/ensalada-clasica.jpg)'} ,
                      photo:'ensaladas/clasica/ensalada-clasica.jpg',
                      description: 'lechuga, tomate, pepinillo, zanahoria, beterraga y Brócoli (palta) ',
                      price: 4
                    },{
                      name: ' Ensalada Cocida  ',
                      nameId:'ensalada-cocida',
                      bg:{'background-image':'url(images/platos/square/ensaladas/cocida/ensalada-cocida.jpg)'} ,
                      photo:'ensaladas/cocida/ensalada-cocida.jpg',
                      description: 'beterraga, zanahoria, vainita,  brócoli y choclo  ',
                      price: 4
                    },{
                      name: ' Esalada Tedhi's   ',
                      nameId:'ensalada-tedhis',
                      bg:{'background-image':'url(images/platos/square/ensaladas/tedhis/ensalada-tedhis.jpg)'} ,
                      photo:'ensaladas/tedhis/ensalada-tedhis.jpg',
                      subname: 'Nuevo',
                      description: ' lechuga, tomate, pepinillo, beterraga, champiñones, brócoli, choclo y palta  ',
                      price: 6
                    }
                  ]
                },
                {
                  name: 'Sandwich',
                  photo: 'ensalada1.jpg' ,
                  img:{'background-image':'url(images/portadas/standar/sandwich1.jpg)'}
                  ,plates: [
                    {
                      name: ' Sandwich de pollo ',
                      nameId:'sandwiche-de-pollo',
                      bg:{'background-image':'url(images/platos/square/sandwich-de-pollo/sandwiche-de-pollo.jpg)'} ,
                      photo:'sandwich-de-pollo/sandwiche-de-pollo.jpg',
                      description: 'Pollo bañado con mayonesa, lechuga y unas rodajas de tomate, acompañados con crocantes papas fritas ,',
                      price: 4
                    },{
                      name: ' Hamburguesa ',
                      nameId:'hamburguesa-simple',
                      bg:{'background-image':'url(images/platos/square/hamburguesa/simple/hamburguesa-simple.jpg)'} ,
                      photo:'hamburguesa/simple/hamburguesa-simple.jpg',
                      description: 'Deliciosa hamburguesa de carne, lechuga y unas rodajas de tomate, acompañados con crocantes papas fritas',
                      price: 4
                    },{
                      name: ' Hamburguesa Royal ',
                      nameId:'hamburguesa-roryal',
                      bg:{'background-image':'url(images/platos/square/hamburguesa/royal/hamburguesa-roryal.jpg)'} ,
                      photo:'hamburguesa/royal/hamburguesa-roryal.jpg',
                      description: 'Una jugosa hamburguesa de carne, con huevo frito y queso edam, lechuga, unas rodajas de tomate, acompañada con crocantes papas fritas',
                      price: 7
                    }
                  ]
                },
                {
                  name: 'Jugos',
                  photo: 'jugos1.jpg' ,
                  img:{'background-image':'url(images/portadas/standar/jugos1.jpg)'}
                  ,plates: [
                    {
                      name: ' Jugos',
                      subname:'(Piña, Papaya, Surtido, Naranja)',
                      price: 4
                    },
                    {
                      name: ' Especial con leche ',
                      price: 7
                    },
                    {
                      name: ' Especial con Malta  ',
                      subname: '(1/2 jarra)',
                      price: 10
                    },
                    {
                      name: ' Milshake  ',
                      price: 10
                    }
                  ]
                },
                {
                  name: 'Helados',
                  photo: 'helados1.jpg' ,
                  img:{'background-image':'url(images/portadas/standar/helados1.jpg)'}
                  ,plates: [
                    {
                      name: ' Copa Simple',
                      description: '2 Bolas',
                      price: 3
                    },
                    {
                      name: ' Copa campero',
                      description: '3 Bolas',
                      price: 7
                    }
                  ]
                },
                {
                  name: 'Bebidas Frias',
                  photo: 'bebidas-frias1.jpg' ,
                  img:{'background-image':'url(images/portadas/standar/bebidas-frias1.jpg)'}
                  ,plates: [
                    {
                      name: 'Chicha Morada ',
                      subname: '(Jarra)',
                      description: '',
                      price: 7
                    },{
                      name: 'Gaseosa mediana',
                      description: '',
                      price: 1.5
                    },{
                      name: 'Gaseosa de 1/2',
                      description: '',
                      price: 2
                    },{
                      name: 'Gaseosa de 1 1/2',
                      description: '',
                      price: 7
                    },{
                      name: 'Gaseosa de 2 Lts.',
                      description: '',
                      price: 8
                    },{
                      name: 'Gaseosa de 3 Lts.',
                      description: '',
                      price: 10
                    },{
                      name: 'Limonada frozen',
                      description: '',
                      price: 10
                    },
                  ]
                },
                {
                  name: 'Bebidas Calientes',
                  photo: 'bebidas-calientes1.jpg' ,
                  img:{'background-image':'url(images/portadas/standar/bebidas-calientes1.jpg)'}
                  ,plates: [
                    {
                      name: ' Taza de café con Leche ',
                      price: 2.5
                    },
                    {
                      name: ' Taza de café ',
                      price: 2.0
                    },
                    {
                      name: ' Infusiones (Taza) ',
                      price: 2.0
                    }
                  ]
                },
                {
                  name: 'Cocktails',
                  photo: 'cocktails1.jpg' ,
                  img:{'background-image':'url(images/portadas/standar/cocktails1.jpg)'}
                  ,plates: [
                    {
                      name: ' Pisco Sour ',
                      price: 7
                    },{
                      name: ' Cocktail Algarrobina ',
                      price: 7
                    },{
                      name: ' Menta Frappé ',
                      price: 7
                    },{
                      name: ' Chilcano de Pisco ',
                      price: 7
                    },{
                      name: ' Gin con Gin ',
                      price: 7
                    },{
                      name: ' Belliny ',
                      price: 7
                    },{
                      name: ' Perú Libre ',
                      price: 7
                    },{
                      name: ' Piña Colada ',
                      price: 7
                    },{
                      name: ' Sangria (Jarra)',
                      price: 20
                    },{
                      name: '1/2 Sangria (Jarra) ',
                      price: 10
                    }

                  ]
                },
                {
                  name: 'Licores en Botella',
                  photo: 'licors1.jpg' ,
                  img:{'background-image':'url(images/portadas/standar/licors1.jpg)'}
                  ,plates: [
                    {
                      name: ' Cerveza Jarra 1.200 Lt. ',
                      price: 10
                    },{
                      name: ' Malta polar chica  ',
                      price: 5
                    },{
                      name: ' Cerveza Cristal chica  ',
                      price: 5
                    },{
                      name: ' Vino Tacama botella  ',
                      price: 30
                    },{
                      name: ' Vino Blanco Viña Vieja 750 ml.  ',
                      price: 25
                    },{
                      name: ' Vino Tinto Viña Vieja 750 ml.  ',
                      price: 25
                    },{
                      name: 'Vino Borgoña Copello 750 ml.  ',
                      price: 22
                    },{
                      name: ' Vino Borgoña Viña Vieja  ',
                      price: 25
                    },{
                      name: ' Vino Tacama Rose ',
                      price: 30
                    },{
                      name: 'Vino Viña Vieja Rose ',
                      price: 25
                    },{
                      name: 'Vino Concha y Toro (Casillero del Diablo)  ',
                      price: 38
                    },{
                      name: ' Vino Ocucaje FON DE CAVE  ',
                      price: 30
                    },{
                      name: ' Vino Viña Vieja copa ',
                      price: 6
                    }
                  ]
                }
              ];

            }]
          }
        }
      })

      .state('carta.show',{
        url:'/{id:[a-zA-Z]{1,25}}',
        views:{
          'item':{
            templateUrl:'app/js/carta/list.html',
            controller:['$scope',function($scope){
              console.log("list");
              $scope.title= 'Carta';
            }]
          }
        }
      })

      .state('promociones',{
        url:'/promociones',
        templateUrl:'app/js/promociones/index.html',
        controller:['$scope',function($scope){
        	console.log('carta');
        }],
        controllerAs:'vm'
      })
      .state('ubicacion',{
        url:'/ubicacion',
        templateUrl:'app/js/ubicacion/index.html',
        controller:['$scope',function($scope){
          var myLatlng = new google.maps.LatLng(-6.770498, -79.839088);
          var mapOptions = {
            zoom: 18,
            center: myLatlng
          }
          var map = new google.maps.Map(document.getElementById('map'), mapOptions);

          var marker = new google.maps.Marker({
              position: myLatlng,
              icon:'images/icon-map.png',
              map: map,
              title: 'Eras Hotel'
          });
          marker.setMap(map);
        }],
        controllerAs:'vm'
      })
      .state('nosotros',{
        url:'/nosotros',
        templateUrl:'app/js/nosotros/index.html',
        controller:['$scope',function($scope){
        	var slider = new IdealImageSlider.Slider({
            selector: '#slider',
            effect: 'fade'
          });
          slider.start();
        }],
        controllerAs:'vm'
      })

      .state('contactanos',{
        url:'/contactanos',
        templateUrl:'app/js/contactanos/index.html',
        controller:['$scope',function($scope){
          console.log('contactanos');
        }],
        controllerAs:'vm'
      })
      .state('local',{
        url:'/local',
        templateUrl:'app/js/local/index.html',
        controller:['$scope',function($scope){

        }],
        controllerAs:'vm'
      })
      .state('eventos',{
        url:'/eventos',
        templateUrl:'app/js/eventos/index.html',
        controller:['$scope',function($scope){

        }],
        controllerAs:'vm'
      })

  }]);

  app.directive('content', ['$verge', function($verge){
    // Runs during compile
    return {
      // name: '',
      // priority: 1,
      // terminal: true,
      // scope: {}, // {} = isolate, true = child, false/undefined = no change
      // controller: function($scope, $element, $attrs, $transclude) {},
      // require: 'ngModel', // Array = multiple requires, ? = optional, ^ = check parent elements
      restrict: 'C', // E = Element, A = Attribute, C = Class, M = Comment
      // template: '',
      // templateUrl: '',
      // replace: true,
      // transclude: true,
      // compile: function(tElement, tAttrs, function transclude(function(scope, cloneLinkingFn){ return function linking(scope, elm, attrs){}})),
      link: function($scope, element, iAttrs) {
         if( element[0].clientHeight <= $verge.viewportH()){
          console.log($verge);
          element.css('height', $verge.viewportH() );
        }
      }
    };
  }]);

  app.directive('plate', ['$verge', function($verge){
    // Runs during compile
    return {
      // name: '',
      // priority: 1,
      // terminal: true,
      // scope: {}, // {} = isolate, true = child, false/undefined = no change
      // controller: function($scope, $element, $attrs, $transclude) {},
      // require: 'ngModel', // Array = multiple requires, ? = optional, ^ = check parent elements
      restrict: 'C', // E = Element, A = Attribute, C = Class, M = Comment
      // template: '',
      // templateUrl: '',
      // replace: true,
      // transclude: true,
      // compile: function(tElement, tAttrs, function transclude(function(scope, cloneLinkingFn){ return function linking(scope, elm, attrs){}})),
      link: function($scope, element, attrs) {
        var img = element.find('img').eq(0);
        console.log(img.attr('ng-src') );
      }
    };
  }]);

})(angular,jQuery,  window);


text:
namespace crazy {

namespace {

inline bool PageEquals(const char* p1, const char* p2) {
  return ::memcmp(p1, p2, PAGE_SIZE) == 0;
}

// Swap pages between |addr| and |addr + size| with the bytes
// from the ashmem region identified by |fd|, starting from
// a given |offset|. On failure return false and set |error| message.
bool SwapPagesFromFd(void* addr,
                     size_t size,
                     int fd,
                     size_t offset,
                     Error* error) {
  // Unmap current pages.
  if (::munmap(addr, size) < 0) {
    error->Format("%s: Could not unmap %p-%p: %s",
                  __FUNCTION__,
                  addr,
                  (char*)addr + size,
                  strerror(errno));
    return false;
  }

  // Remap the fd pages at the same location now.
  void* new_map = ::mmap(addr,
                         size,
                         PROT_READ,
                         MAP_FIXED | MAP_SHARED,
                         fd,
                         static_cast<off_t>(offset));
  if (new_map == MAP_FAILED) {
    char* p = reinterpret_cast<char*>(addr);
    error->Format("%s: Could not map %p-%p: %s",
                  __FUNCTION__,
                  p,
                  p + size,
                  strerror(errno));
    return false;
  }

// TODO(digit): Is this necessary?
#ifdef __arm__
  __clear_cache(addr, (char*)addr + size);
#endif

  // Done.
  return true;
}

}  // namespace

bool SharedRelro::Allocate(size_t relro_size,
                           const char* library_name,
                           Error* error) {
  // Allocate a new ashmem region.
  String name("RELRO:");
  name += library_name;
  if (!ashmem_.Allocate(relro_size, name.c_str())) {
    error->Format("Could not allocate RELRO ashmem region for %s: %s",
                  library_name,
                  strerror(errno));
    return false;
  }

  start_ = 0;
  size_ = relro_size;
  return true;
}

bool SharedRelro::CopyFrom(size_t relro_start,
                           size_t relro_size,
                           Error* error) {
  // Map it in the process.
  ScopedMemoryMapping map;
  if (!map.Allocate(NULL, relro_size, MemoryMapping::CAN_WRITE, ashmem_.fd())) {
    error->Format("Could not allocate RELRO mapping: %s", strerror(errno));
    return false;
  }

  // Copy process' RELRO into it.
  ::memcpy(map.Get(), reinterpret_cast<void*>(relro_start), relro_size);

  // Unmap it.
  map.Deallocate();

  // Everything's good.
  start_ = relro_start;
  size_ = relro_size;
  return true;
}

bool SharedRelro::CopyFromRelocated(const ElfView* view,
                                    size_t load_address,
                                    size_t relro_start,
                                    size_t relro_size,
                                    Error* error) {
  // Offset of RELRO section in current library.
  size_t relro_offset = relro_start - view->load_address();

  ElfRelocations relocations;
  if (!relocations.Init(view, error))
    return false;

  // Map the region in memory (any address).
  ScopedMemoryMapping map;
  if (!map.Allocate(
           NULL, relro_size, MemoryMapping::CAN_READ_WRITE, ashmem_.fd())) {
    error->Format("Could not allocate RELRO mapping for: %s", strerror(errno));
    return false;
  }

  // Copy and relocate.
  relocations.CopyAndRelocate(relro_start,
                              reinterpret_cast<size_t>(map.Get()),
                              load_address + relro_offset,
                              relro_size);
  // Unmap it.
  map.Deallocate();
  start_ = load_address + relro_offset;
  size_ = relro_size;
  return true;
}

bool SharedRelro::ForceReadOnly(Error* error) {
  // Ensure the ashmem region content isn't writable anymore.
  if (!ashmem_.SetProtectionFlags(PROT_READ)) {
    error->Format("Could not make RELRO ashmem region read-only: %s",
                  strerror(errno));
    return false;
  }
  return true;
}

bool SharedRelro::InitFrom(size_t relro_start,
                           size_t relro_size,
                           int ashmem_fd,
                           Error* error) {
  // Create temporary mapping of the ashmem region.
  ScopedMemoryMapping fd_map;

  LOG("%s: Entering addr=%p size=%p fd=%d\n",
      __FUNCTION__,
      (void*)relro_start,
      (void*)relro_size,
      ashmem_fd);

  // Sanity check: Ashmem file descriptor must be read-only.
  if (!AshmemRegion::CheckFileDescriptorIsReadOnly(ashmem_fd)) {
    error->Format("Ashmem file descriptor is not read-only: %s\n",
                  strerror(errno));
    return false;
  }

  if (!fd_map.Allocate(NULL, relro_size, MemoryMapping::CAN_READ, ashmem_fd)) {
    error->Format("Cannot map RELRO ashmem region as read-only: %s\n",
                  strerror(errno));
    return false;
  }

  LOG("%s: mapping allocated at %p\n", __FUNCTION__, fd_map.Get());

  char* cur_page = reinterpret_cast<char*>(relro_start);
  char* fd_page = static_cast<char*>(fd_map.Get());
  size_t p = 0;
  size_t size = relro_size;
  size_t similar_size = 0;

  do {
    // Skip over dissimilar pages.
    while (p < size && !PageEquals(cur_page + p, fd_page + p)) {
      p += PAGE_SIZE;
    }

    // Count similar pages.
    size_t p2 = p;
    while (p2 < size && PageEquals(cur_page + p2, fd_page + p2)) {
      p2 += PAGE_SIZE;
    }

    if (p2 > p) {
      // Swap pages between |pos| and |pos2|.
      LOG("%s: Swap pages at %p-%p\n",
          __FUNCTION__,
          cur_page + p,
          cur_page + p2);
      if (!SwapPagesFromFd(cur_page + p, p2 - p, ashmem_fd, p, error))
        return false;

      similar_size += (p2 - p);
    }

    p = p2;
  } while (p < size);

  LOG("%s: Swapped %d pages over %d (%d %%, %d KB not shared)\n",
      __FUNCTION__,
      similar_size / PAGE_SIZE,
      size / PAGE_SIZE,
      similar_size * 100 / size,
      (size - similar_size) / 4096);

  if (similar_size == 0) {
    error->Format("No pages were swapped into RELRO ashmem");
    return false;
  }

  start_ = relro_start;
  size_ = relro_size;
  return true;
}

}  // namespace crazy