138a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes//===----------- ImmutableSetTest.cpp - ImmutableSet unit tests ------------===// 2c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes// 3c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes// The LLVM Compiler Infrastructure 4c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes// 5c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes// This file is distributed under the University of Illinois Open Source 6c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes// License. See LICENSE.TXT for details. 7c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes// 8c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes//===----------------------------------------------------------------------===// 9c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 10c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes#include "gtest/gtest.h" 11c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes#include "llvm/ADT/ImmutableSet.h" 12c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 13c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopesusing namespace llvm; 14c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 15c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopesnamespace { 16c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopesclass ImmutableSetTest : public testing::Test { 1738a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopesprotected: 1838a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes // for callback tests 1938a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes static char buffer[10]; 2038a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes 2138a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes struct MyIter { 2238a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes int counter; 2338a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes char *ptr; 2438a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes 2538a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes MyIter() : counter(0), ptr(buffer) { 2638a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes for (unsigned i=0; i<sizeof(buffer);++i) buffer[i]='\0'; 2738a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes } 2838a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes void operator()(char c) { 2938a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes *ptr++ = c; 3038a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes ++counter; 3138a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes } 3238a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes }; 33c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes}; 3438a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopeschar ImmutableSetTest::buffer[10]; 35c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 36c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 37c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno LopesTEST_F(ImmutableSetTest, EmptyIntSetTest) { 38c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes ImmutableSet<int>::Factory f; 39c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 409c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek EXPECT_TRUE(f.getEmptySet() == f.getEmptySet()); 419c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek EXPECT_FALSE(f.getEmptySet() != f.getEmptySet()); 429c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek EXPECT_TRUE(f.getEmptySet().isEmpty()); 43c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 449c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<int> S = f.getEmptySet(); 45c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_EQ(0u, S.getHeight()); 46c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S.begin() == S.end()); 47c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S.begin() != S.end()); 48c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes} 49c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 50c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 51c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno LopesTEST_F(ImmutableSetTest, OneElemIntSetTest) { 52c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes ImmutableSet<int>::Factory f; 539c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<int> S = f.getEmptySet(); 54c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 559c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<int> S2 = f.add(S, 3); 56c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S.isEmpty()); 57c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S2.isEmpty()); 58c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S == S2); 59c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S != S2); 60c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S.contains(3)); 61c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S2.contains(3)); 62c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S2.begin() == S2.end()); 63c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S2.begin() != S2.end()); 64c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 659c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<int> S3 = f.add(S, 2); 66c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S.isEmpty()); 67c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S3.isEmpty()); 68c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S == S3); 69c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S != S3); 70c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S.contains(2)); 71c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S3.contains(2)); 72c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 73c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S2 == S3); 74c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S2 != S3); 75c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S2.contains(2)); 76c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S3.contains(3)); 77c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes} 78c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 79c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno LopesTEST_F(ImmutableSetTest, MultiElemIntSetTest) { 80c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes ImmutableSet<int>::Factory f; 819c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<int> S = f.getEmptySet(); 82c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 839c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<int> S2 = f.add(f.add(f.add(S, 3), 4), 5); 849c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<int> S3 = f.add(f.add(f.add(S2, 9), 20), 43); 859c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<int> S4 = f.add(S2, 9); 86c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 87c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S.isEmpty()); 88c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S2.isEmpty()); 89c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S3.isEmpty()); 90c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S4.isEmpty()); 91c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 92c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S.contains(3)); 93c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S.contains(9)); 94c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 95c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S2.contains(3)); 96c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S2.contains(4)); 97c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S2.contains(5)); 98c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S2.contains(9)); 99c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S2.contains(0)); 100c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 101c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S3.contains(43)); 102c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S3.contains(20)); 103c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S3.contains(9)); 104c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S3.contains(3)); 105c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S3.contains(4)); 106c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S3.contains(5)); 107c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S3.contains(0)); 108c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 109c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S4.contains(9)); 110c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S4.contains(3)); 111c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S4.contains(4)); 112c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S4.contains(5)); 113c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S4.contains(20)); 114c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S4.contains(43)); 115c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes} 116c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 117c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno LopesTEST_F(ImmutableSetTest, RemoveIntSetTest) { 118c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes ImmutableSet<int>::Factory f; 1199c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<int> S = f.getEmptySet(); 120c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 1219c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<int> S2 = f.add(f.add(S, 4), 5); 1229c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<int> S3 = f.add(S2, 3); 1239c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<int> S4 = f.remove(S3, 3); 124c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 125c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S3.contains(3)); 126c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S2.contains(3)); 127c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_FALSE(S4.contains(3)); 128c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 129c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S2 == S4); 130c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S3 != S2); 131c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S3 != S4); 132c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 133c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S3.contains(4)); 134c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S3.contains(5)); 135c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 136c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S4.contains(4)); 137c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes EXPECT_TRUE(S4.contains(5)); 138c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes} 139c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 140c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno LopesTEST_F(ImmutableSetTest, CallbackCharSetTest) { 141c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes ImmutableSet<char>::Factory f; 1429c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<char> S = f.getEmptySet(); 143c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 1449c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<char> S2 = f.add(f.add(f.add(S, 'a'), 'e'), 'i'); 1459c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<char> S3 = f.add(f.add(S2, 'o'), 'u'); 146c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 147c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes S3.foreach<MyIter>(); 148c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 14938a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes ASSERT_STREQ("aeiou", buffer); 150c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes} 151c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 152c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno LopesTEST_F(ImmutableSetTest, Callback2CharSetTest) { 153c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes ImmutableSet<char>::Factory f; 1549c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<char> S = f.getEmptySet(); 155c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 1569c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<char> S2 = f.add(f.add(f.add(S, 'b'), 'c'), 'd'); 1579c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<char> S3 = f.add(f.add(f.add(S2, 'f'), 'g'), 'h'); 158c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 159c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes MyIter obj; 160c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes S3.foreach<MyIter>(obj); 16138a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes ASSERT_STREQ("bcdfgh", buffer); 16238a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes ASSERT_EQ(6, obj.counter); 163c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 16438a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes MyIter obj2; 16538a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes S2.foreach<MyIter>(obj2); 16638a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes ASSERT_STREQ("bcd", buffer); 16738a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes ASSERT_EQ(3, obj2.counter); 168c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 16938a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes MyIter obj3; 170c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes S.foreach<MyIter>(obj); 17138a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes ASSERT_STREQ("", buffer); 17238a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes ASSERT_EQ(0, obj3.counter); 173c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes} 174c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 175c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno LopesTEST_F(ImmutableSetTest, IterLongSetTest) { 176c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes ImmutableSet<long>::Factory f; 1779c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<long> S = f.getEmptySet(); 178c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 1799c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<long> S2 = f.add(f.add(f.add(S, 0), 1), 2); 1809c336fabd59fbdbe9129d76fbbee32261ac7c8f0Ted Kremenek ImmutableSet<long> S3 = f.add(f.add(f.add(S2, 3), 4), 5); 181c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 182c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes int i = 0; 183c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes for (ImmutableSet<long>::iterator I = S.begin(), E = S.end(); I != E; ++I) { 18438a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes ASSERT_EQ(i++, *I); 185c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes } 18638a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes ASSERT_EQ(0, i); 187c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 188c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes i = 0; 189c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes for (ImmutableSet<long>::iterator I = S2.begin(), E = S2.end(); I != E; ++I) { 19038a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes ASSERT_EQ(i++, *I); 191c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes } 19238a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes ASSERT_EQ(3, i); 193c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 194c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes i = 0; 195c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes for (ImmutableSet<long>::iterator I = S3.begin(), E = S3.end(); I != E; I++) { 19638a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes ASSERT_EQ(i++, *I); 197c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes } 19838a2cb93795facfad8fa15a074a3a8d4da11f876Nuno Lopes ASSERT_EQ(6, i); 199c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes} 200c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes 201c3651569c1e5a8ef93afef3d4b5ea961a3821784Nuno Lopes} 202