C# Return a Copy of ConcurrentBag - c#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Concurrent;
namespace Crystal_Message
{
class Message
{
private int messageID;
private string message;
private ConcurrentBag <Employee> messageFor;
private Person messageFrom;
private string calltype;
public Message(int iden,string message, Person messageFrom, string calltype, string telephone)
{
this.messageID = iden;
this.messageFor = new ConcurrentBag<Employee>();
this.Note = message;
this.MessageFrom = messageFrom;
this.CallType = calltype;
}
public ConcurrentBag<Employee> ReturnMessageFor
{
get
{
return messageFor;
}
}
public int MessageIdentification
{
get { return this.messageID; }
private set
{
if(value == 0)
{
throw new ArgumentNullException("Must have Message ID");
}
this.messageID = value;
}
}
public string Note
{
get { return message; }
private set
{
if (string.IsNullOrWhiteSpace(value))
{
throw new ArgumentException("Must Have a Message");
}
this.message = value;
}
}
public Person MessageFrom
{
get { return messageFrom; }
private set
{
this.messageFrom = value;
}
}
public string CallType
{
get { return this.calltype; }
private set
{
if (string.IsNullOrWhiteSpace(value))
{
throw new ArgumentNullException("Please specify call type");
}
this.calltype = value;
}
}
public void addEmployee(Employee add)
{
messageFor.Add(add);
}
public override string ToString()
{
return "Message: " + this.message + " From: " + this.messageFrom + " Call Type: " + this.calltype + " For: " + this.returnMessagefor();
}
private string returnMessagefor()
{
string generate="";
foreach(Employee view in messageFor)
{
generate += view.ToString() + " ";
}
return generate;
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
Message testEquals = obj as Message;
if((System.Object)testEquals == null)
{
return false;
}
return (this.messageID == testEquals.messageID) && (this.message == testEquals.message) && (this.messageFor == testEquals.messageFor) && (this.messageFrom == testEquals.messageFrom) && (this.calltype == testEquals.calltype);
}
public bool Equals(Message p)
{
if ((Object)p == null)
{
return false;
}
return (this.messageID == p.messageID) && (this.message == p.message) && (this.messageFor == p.messageFor) && (this.messageFrom == p.messageFrom) && (this.calltype == p.calltype);
}
public override int GetHashCode()
{
unchecked
{
return this.messageID.GetHashCode() * 33 ^ this.message.GetHashCode() * 33 ^ this.messageFor.GetHashCode() * 33 ^ this.messageFrom.GetHashCode() * 33 ^ this.calltype.GetHashCode();
}
}
}
}
I have a Message class where a user could leave a message for more than one person. I have a getter for it, however, is returning a ConcurrentBag<> the way I've done proper practice? If not, how do i return the ConcurrentBag<> so I can loop through it and display it?

ConcurrentBag<T> is an IEnumerable<T>. You can loop through it as usual. However, as this is a thread safe collection, there are performance concerns to using it.
If you want to get rid of the performance impact while looping, call ToArray on it and return the new array instead.
public IEnumerable<Employee> ReturnMessageFor
{
get
{
return messageFor.ToArray();
}
}

It's not clear to me what you are trying to accomplish.
Are you trying to externalize the Bag for all operations? Because that's what you did...
If you want to externalize something you can iterate over you should either return the Bag as IEnumerable or return an array or a list copied from the Bag.
Either way it's safe to iterate over. Might not be the best in terms of performance, but that's another question.
// Option 1
public IEnumerable<Employee> ReturnMessageFor
{
get
{
return messageFor;
}
}
// Option 2
public Employee[] ReturnMessageFor
{
get
{
return messageFor.ToArray();
}
}
Notes:
You might want to make messageFor readonly (in the code you posted it is readonly).
Remember that a ConcurrentBag allows you to safely iterate over a snapshot of the collection in a thread safe manner, but it does not lock the items in the collection.

Related

Executing same function from several async methods simultenously causes errors

Here is a piece of code, where I try to execute different async methods, that need to be executed in specific order (the await, and Task.WhenAll() parts).
//Some other tasks before
Task<bool> taskIfcQuantityArea = Task.Run<bool>(() =>
{
return this.addGroupStringToDictionary("IfcQuantityArea");
});
Task<bool> taskIfcQuantityLength = Task.Run<bool>(() =>
{
return this.addGroupStringToDictionary("IfcQuantityLength");
});
Task<bool> taskIfcSiUnit = Task.Run<bool>(() =>
{
return addGroupStringToDictionary("IfcSiUnit");
});
Task<bool> taskIfcPropertySingleValue = Task.Run<bool>(() =>
{
return addGroupStringToDictionary("IfcPropertySingleValue");
});
//uses IfcPerson, IfcOrganization
Task<bool> taskIfcPersonAndOrganization = Task.Run<bool>(() =>
{
return addGroupStringToDictionary("IfcPersonAndOrganization");
});
//uses IfcOrganization
Task<bool> taskIfcApplication = Task.Run(async () =>
{
await taskIfcSiUnit;
return addGroupStringToDictionary("IfcApplication");
});
//uses IfcSiUnit
Task<bool> taskIfcMeasureWithUnit = Task.Run(async () =>
{
await taskIfcSiUnit;
return addGroupStringToDictionary("IfcMeasureWithUnit");
});
//some other tasks after.
When I do that job synchronously, all works fine, but when I do it in async, I have some random errors. At every test, the errors come randomly.
The only thing I see that could go wrong, is they all execute the same function addGroupStringToDictionary.
Here is the function :
private bool addGroupStringToDictionary(string typeName)
{
//int processCount = await Task.Run<int>(() =>
//{
GroupedListStrings groupElt = this.listGrouppedStrings.FirstOrDefault(x => x.Type == typeName.ToUpper());
if (groupElt != null)
{
List<string> listStringInGroup = groupElt.ListStrings;
foreach (string line in listStringInGroup)
{
try
{
if(typeName== "IfcLocalPlacement($")
{
typeName = "IfcLocalPlacement";
}
var type = Type.GetType("Ifc."+typeName);
if (typeName == "IfcPropertySingleValue" || typeName == "IfcDirection" || typeName == "IfcSiUnit" || typeName == "IfcQuantityLength" || typeName == "IfcQuantityArea" || typeName == "IfcQuantityVolume" || typeName == "IfcQuantityWeight")
{
try
{
object instance = Activator.CreateInstance(type, line);
this.addToListDictionary((IfcElement)instance);
}
catch
{
}
}
else if (typeName == "IfcOpeningElement")
{
try
{
object instance = Activator.CreateInstance(type, line, this.listDictionaries, this.DictionaryBolts);
this.addToListDictionary((IfcElement)instance);
}
catch
{
}
}
else
{
try
{
object instance = Activator.CreateInstance(type, line, this.listDictionaries);
this.addToListDictionary((IfcElement)instance);
}
catch
{
}
}
}
catch
{
this.addError(line);
}
}
this.listGrouppedStrings.Remove(groupElt);
this.reportProgressImport();
}
//return 100;
//});
this.reportProgressImport();
return true;
}
The catch got 1-2 times over a bit more than 1 million lines.
At each test the errors come randomly.
Is it possible that running the function simultaneously from several async methods, this is what causes the problem?
Here is the addToListDictionary function :
private void addToListDictionary(IfcElement elt)
{
if(elt.ErrorFound)
{
this.listReadButError.Add(elt);
return;
}
string type = elt.GetType().ToString();
if (elt is IfcRepere)
{
type = "Ifc.IfcRepere";
}
else if (elt is IfcRepereType)
{
type = "Ifc.IfcRepereType";
}
else if (elt is IfcPhysicalSimpleQuantity)
{
type = "Ifc.IfcPhysicalSimpleQuantity";
}
else if (elt is IfcProfileDef)
{
type = "Ifc.IfcProfileDef";
}
else if (elt is IfcGeometricRepresentationContext)
{
type = "Ifc.IfcGeometricRepresentationContext";
}
GroupDictionary group = this.ListDictionaries.FirstOrDefault(x => x.Name == type);
if(group==null)
{
group = new GroupDictionary { Name = type };
this.ListDictionaries.Add(group);
}
group.ListElements[elt.ID] = elt;
if (elt is IfcMechanicalFastener)
{
IfcMechanicalFastener bolt = (IfcMechanicalFastener)elt;
this.DictionaryBolts[bolt.Tag] = bolt;
}
else if(elt is IfcProject)
{
this.listProjects.Add((IfcProject)elt);
}
else if(elt is IfcElementAssembly ifcAss)
{
this.DictionaryIfcElementAssemblies[ifcAss.Key] = ifcAss;
}
}
Also some additive information about my ListDictionaries :
private List<GroupDictionary> listDictionaries = new List<GroupDictionary>();
public List<GroupDictionary> ListDictionaries { get { return this.listDictionaries; } set { this.listDictionaries = value; } }
And the class GroupDictionary
public class GroupDictionary
{
string name { get; set; }
public string Name { get { return this.name; } set { this.name = value; } }
public ConcurrentDictionary<int, IfcElement> ListElements = new ConcurrentDictionary<int, IfcElement>();
public GroupDictionary()
{
}
}
I made different GroupDictionary because as soon as I don't need one of them, I delete it to free space.
I have one dictionary with IfcPoint, I need it to gt IfcPolyLine (lines), but when I finish to treat all objects using IfcPoint, I clear remove the corresponding GroupDictionary in order to free some memory.
You have a obvious thread-safety issues here (i.e. you are trying to perform some operation which is not thread safe from multiple threads at a time). There are multiple ways you can try tackling it - using locks, or some synchronization primitives.
But in this case it seems that major source of issues is working with standard collections from multiple threads, which is not thread-safe (because thread-safety usually comes with performance price and is not always needed). You can start from switching to appropriate collections from System.Collections.Concurrent namespace.
To go down deeper I recommend free e-book by Joseph Albahari Threading in C#.

Binary search tree using stack

I'm attempting to create a binary search tree without using a recursion to walk through the tree. The code attached works for initializing the tree, but when I try to walk through it, it keeps giving me the "object reference not set to instant of object" when trying to push to the stack in the GetEnumerator() method. I realize that this means I need to push an instance instead of the class itself, but how can I make an instance of "this", so to speak? Or is the only way to implement with stack is to create a separate class that holds the tree? The code is as below:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class BinarySearchTree : IEnumerable<int>
{
public int value;
public BinarySearchTree left;
public BinarySearchTree right;
Stack<BinarySearchTree> stacks;
public BinarySearchTree(int value)
{
this.value = value;
}
public BinarySearchTree(IEnumerable<int> values)
{
this.value = values.First();
foreach (var val in values.Skip(1))
{
this.Add(val);
}
}
public int Value
{
get
{
return this.value;
}
}
public BinarySearchTree Left
{
get
{
return this.left;
}
}
public BinarySearchTree Right
{
get
{
return this.right;
}
}
public void Add(int value)
{
BinarySearchTree current_node = this;
while (current_node.left != null && current_node.right != null)
{
if (value <= current_node.value)
{
current_node = current_node.left;
}
else
{
current_node = current_node.right;
}
}
if (value <= current_node.value)
{
current_node.left = new BinarySearchTree(value);
//return current_node;
}
else
{
current_node.right = new BinarySearchTree(value);
//return current_node;
}
}
public BinarySearchTree GetValueAtNode()
{
}
public IEnumerator<int> GetEnumerator()
{
BinarySearchTree current_node = this;
stacks.Push(current_node);
while (stacks.Count != 0){
if (current_node.left != null)
{
stacks.Push(current_node);
current_node = current_node.left;
}
yield return stacks.Peek().value;
current_node = stacks.Peek().right;
stacks.Pop();
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
The error message is:
BinarySearchTreeTests.Can_sort_complex_tree:
Outcome: Failed
Error Message:
System.NullReferenceException : Object reference not set to an instance of an object.
Stack Trace:
at BinarySearchTree.GetEnumerator()+MoveNext() in c:\Users\320145763\Exercism\csharp\binary-search-tree\BinarySearchTree.cs:line 78
at BinarySearchTreeTests.Can_sort_complex_tree() in c:\Users\320145763\Exercism\csharp\binary-search-tree\BinarySearchTreeTests.cs:line 84
And the relevant unit test is:
using System.Linq;
using Xunit;
public class BinarySearchTreeTests
{
[Fact]
public void Can_sort_complex_tree()
{
var tree = new BinarySearchTree(new[] { 2, 1, 3, 6, 7, 5 });
Assert.Equal(new[] { 1, 2, 3, 5, 6, 7 }, tree.AsEnumerable());
}
}
Some issues:
The while condition in Add is not correct, it could be that just one child reference is null and that the code that follows the while loop will overwrite the existing child reference, whereby you will potentially lose part of the tree. It is probably easiest to do a while (true) and break out of the loop as soon as in the direction of choice there is no child and a new node is created to fill that gap.
stacks should not be an instance member, but a variable local to GetEnumerator as otherwise you will get two executing GetEnumerator iterators to interfere which each other's stack needs.
stacks is never initialised to be an actual Stack instance. You need new Stack<BinarySearchTree>() somewhere...
The logic of GetEnumerator is not (entirely) correct. For instance current_node = stacks.Peek().right; may assign null to current_node so that you get an exception in the next iteration.
Here is a correction to the two impacted methods:
public void Add(int value)
{
BinarySearchTree current_node = this;
while (true)
{
if (value <= current_node.value) {
if (current_node.left == null) {
current_node.left = new BinarySearchTree(value);
break;
}
current_node = current_node.left;
} else {
if (current_node.right == null) {
current_node.right = new BinarySearchTree(value);
break;
}
current_node = current_node.right;
}
}
}
public IEnumerator<int> GetEnumerator()
{
Stack<BinarySearchTree> stacks = new Stack<BinarySearchTree>();
stacks.Push(this);
while (stacks.Count != 0){
BinarySearchTree current_node = stacks.Peek();
while (current_node.left != null) {
current_node = current_node.left;
stacks.Push(current_node);
}
while (stacks.Count != 0){
current_node = stacks.Peek();
yield return current_node.value;
stacks.Pop();
if (current_node.right != null) {
stacks.Push(current_node.right);
break;
}
}
}
}

Cannot assign to ' ' because it is a 'method group' beginner

I'm practicing on setters and getters, got this error message:
Cannot assign to 'GetnewName' because it is a'method group'
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
public class Program
{
public static void Main(string[] args)
{
Bird b = new Bird();
b.GetnewName = "Tweety";
b.Chirp();
Bird b2 = new Bird();
b2.GetnewName = "Woody";
b2.Chirp();
}
}
public class Bird
{
private string name;
private double weight = 30.5d;
public void SetName(string newName)
{
if (newName != null && newName.Length > 2)
{
System.Console.WriteLine("Bird already has a name");
this.name = newName;
}
else if (newName.Length < 3)
{
System.Console.WriteLine("New name must be longer than two chars");
}
else
{
name = newName;
}
}
public string GetnewName()
{
return this.name;
}
public void Chirp()
{
System.Console.WriteLine(name + " says chirp!");
}
}
}
You need to set name using the SetName method.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
public class Program
{
public static void Main(string[] args)
{
Bird b = new Bird();
b.SetName("Tweety");
b.Chirp();
Bird b2 = new Bird();
b2.SetName("Woody");
b2.Chirp();
Console.ReadLine();
}
}
public class Bird
{
private string name;
private double weight = 30.5d;
public void SetName(string newName)
{
if (newName != null && newName.Length > 2)
{
System.Console.WriteLine("Bird already has a name");
this.name = newName;
}
else if (newName.Length < 3)
{
System.Console.WriteLine("New name must be longer than two chars");
}
else
{
name = newName;
}
}
public string GetnewName()
{
return this.name;
}
public void Chirp()
{
System.Console.WriteLine(name + " says chirp!");
}
}
}
You are using GetnewName as if it were a property, but you defined it as a pair of methods.
Property syntax combines the getter and the setter under a single name. Then C# re-routs assignments to the setter, and reads to the getter method:
public string Name {
get => name
set {
if (value != null && value.Length > 2) {
System.Console.WriteLine("Bird already has a name");
name = value;
} else if (value.Length < 3) {
System.Console.WriteLine("New name must be longer than two chars");
} else {
name = value;
}
}
}
Note: get => name above uses the new syntax. Old syntax for the same was get { return name; }
You cannot assign a string to a method, this causes the error.
I c# we don't use getters and setters as in Java or C++. Instead we have properties which we use. You can assign and read values as if they where fields but they have special methods called accessors. You should refactor your class like this:
public class Bird
{
private string name;
private double weight = 30.5d;
public string Name
{
get => name;
set
{
if (value != null && value.Length > 2)
{
Console.WriteLine("Bird already has a name");
name = value;
}
else if (value != null && value.Length < 3)
{
Console.WriteLine("New name must be longer than two chars");
}
else
{
name = value;
}
}
}
public void Chirp()
{
System.Console.WriteLine(name + " says chirp!");
}
}
Then you can use it as:
var bird = new Bird();
// assign a value (equivalent to SetName method in your original code)
bird.Name = "Woody";
// read a value (equivalent to GetName method in your original code)
Console.WriteLine(bird.Name);
It seems like you want this:
public string Name
{
get; private set;
}
public void SetName(string newName)
{
if (newName != null && newName.Length > 2)
{
System.Console.WriteLine("Bird already has a name");
Name = newName;
}
else if (newName.Length < 3)
{
System.Console.WriteLine("New name must be longer than two chars");
}
else
{
Name = newName;
}
}
The get; will automatically return the value of your property, without the need for a private backing property, and typically you could use the setter inside the property to set the value, but since you need to pass a parameter too it, it seems like making the setter private and creating a separate method to actually set it would suit your needs.

return value only when it is available else wait for the value..... c#

Return the value only when it is available. if I use a condition to check the null condition it is throwing a exception. "saying not all code paths return a value"
internal PinMessage()
{
obj.PinsAvailable.ObserveOn(SynchronizationContext.Current).Subscribe(HandlePinsAvailable);
}
private void HandlePinsAvailable(byte[] pinBytes)
{
pinmesssage = Encoding.ASCII.GetString(pinBytes);
}
internal string GetPinMessage(string AccoutNumber)
{
string pinstring = string.Empty;
obj.SendPinRequest(AccoutNumber);
pinstring = pinmesssage;
return pinstring;
}
private string _pinMessage;
public string pinmesssage
{
get//Not all Code paths return a value
{
if (_pinMessage != null)
return _pinMessage;
}
set { _pinMessage = value; }
}
You are getting this compile error because you don't return anything in the case where _pinMesSafe is null. You need to return something from your Access or in the case when that is true, or throw an exception.
private string _pinMessafe;
public string pinmesssage
{
get {
if (_pinMessafe != null)
return _pinMessafe;
}
set { _pinMessafe = value; }
}
You have to return something when it's being called, you can't just put a method call on hold.
What you could do is force a check yourself:
private string _pinMessafe;
public string pinmesssage
{
get {
return _pinMessafe ?? GetMessage()
}
set { _pinMessafe = value; }
}
In this scenario, GetMessage() would have to take care of returning the message. It's hard to give a more detailed answer with the information you've provided.
You should edit your code to make it more readable (this includes the english spelling errors) and add info if needed.
This is not the "best" practice, but will work and let your consumer wait until the producer has written the variable.
private string _pinMessafe;
object locker = new object();
public string pinmesssage
{
get
{
string x = null;
while(x == null) {
lock(locker) { x = _pinMessafe ; }
Thread.Sleep(1);
}
return x;
}
set { lock(locker) { _pinMessafe = value; } }
}

Elegant way to validate values

I have a class with many fields which represents different physical values.
class Tunnel
{
private double _length;
private double _crossSectionArea;
private double _airDensity;
//...
Each field is exposed using read/write property. I need to check on setter that the value is correct and generate exception otherwise. All validations are similar:
public double Length
{
get { return _length; }
set
{
if (value <= 0) throw new ArgumentOutOfRangeException("value",
"Length must be positive value.");
_length = value;
}
}
public double CrossSectionArea
{
get { return _crossSectionArea; }
set
{
if (value <= 0) throw new ArgumentOutOfRangeException("value",
"Cross-section area must be positive value.");
_crossSectionArea = value;
}
}
public double AirDensity
{
get { return _airDensity; }
set
{
if (value < 0) throw new ArgumentOutOfRangeException("value",
"Air density can't be negative value.");
_airDensity = value;
}
}
//...
Is there any elegant and flexible way to accomplish such validation?
Assuming you want this sort of behaviour, you might consider some helper methods, e.g.
public static double ValidatePositive(double input, string name)
{
if (input <= 0)
{
throw new ArgumentOutOfRangeException(name + " must be positive");
}
return input;
}
public static double ValidateNonNegative(double input, string name)
{
if (input < 0)
{
throw new ArgumentOutOfRangeException(name + " must not be negative");
}
return input;
}
Then you can write:
public double AirDensity
{
get { return _airDensity; }
set
{
_airDensity = ValidationHelpers.ValidateNonNegative(value,
"Air density");
}
}
If you need this for various types, you could even make it generic:
public static T ValidateNonNegative(T input, string name)
where T : IComparable<T>
{
if (input.CompareTo(default(T)) < 0)
{
throw new ArgumentOutOfRangeException(name + " must not be negative");
}
return input;
}
Note that none of this is terribly i18n-friendly...
All depends what technology you are using - if you're under MVC you can use Attributes, like this;
http://msdn.microsoft.com/en-us/library/ee256141(v=vs.98).aspx
Here's my version, it's a bit cleaner than Jon's version in some respects:
interface IValidator <T>
{
bool Validate (T value);
}
class IntValidator : IValidator <int>
{
public bool Validate (int value)
{
return value > 10 && value < 15;
}
}
class Int2Validator : IValidator<int>
{
public bool Validate (int value)
{
return value > 100 && value < 150;
}
}
struct Property<T, P> where P : IValidator<T>, new ()
{
public T Value
{
set
{
if (m_validator.Validate (value))
{
m_value = value;
}
else
{
Console.WriteLine ("Error validating: '" + value + "' is out of range.");
}
}
get { return m_value; }
}
T m_value;
static IValidator<T> m_validator=new P();
}
class Program
{
static void Main (string [] args)
{
Program
p = new Program ();
p.m_p1.Value = 9;
p.m_p1.Value = 12;
p.m_p1.Value = 25;
p.m_p2.Value = 90;
p.m_p2.Value = 120;
p.m_p2.Value = 250;
}
Property<int, IntValidator>
m_p1;
Property<int, Int2Validator>
m_p2;
}
Try to use such a method:
public void FailOrProceed(Func<bool> validationFunction, Action proceedFunction, string errorMessage)
{
// !!! check for nulls, etc
if (!validationFunction())
{
throw new ArgumentOutOfRangeException(errorMessage);
}
proceedFunction();
}
Yes, by creating your own validation attributes.
Read this article: Business Object Validation Using Attributes in C#
I will have the decency of NOT copying it here :)
Using the Validator function I mentioned in my comment above, I'd do something like this (untested code):
void textBox_Changed(object sender, EventArgs e) {
submitButton.Enabled = validator();
}
bool validator() {
const string NON_POSITIVE = "Value must be greater than Zero";
bool result = false;
string controlName = "Length";
try {
_length = Convert.ToDouble(txtLength.Text);
if (_length <= 0) throw new Exception(NON_POSITIVE);
controlName = "Cross Section Area";
_crossSectionArea = Convert.ToDouble(txtCrossSectionArea.Text);
if (_crossSectionArea <= 0) throw new Exception(NON_POSITIVE);
controlName = "Air Density";
_airDensity = Convert.ToDouble(txtAirDensity.Text);
if (_airDensity <= 0) throw new Exception(NON_POSITIVE);
result = true; // only do this step last
} catch (Exception err) {
MessageBox.Show(controlName + " Error: " + err.Message, "Input Error");
}
return result;
}
John Skeet probably has a better way, but this works. :)
You can achieve this using classes from System.ComponentModel.DataAnnotations
class Tunnel
{
[Range(0, double.MaxValue, ErrorMessage = "Length must be positive value.")]
public double Length { get; set; }
}
Validation:
var tunnel = new Tunnel { Length = 0 };
var context = new ValidationContext(tunnel, null, null);
Validator.ValidateObject(tunnel, context, true);
Also you can implement your own validation attributes overriding ValidationAttribute class

Categories