public string GetReport(Portfolio portfolio, IEnumerable<Category> categories, IEnumerable<CategoryWeight> weights)
        {
            var reportBuilder = new StringBuilder();
            var quotes = GetQuotes(portfolio);
            var valuesDict = CalculateValues(portfolio, quotes);
            var weightsList = weights.ToList();

            //DebugPrint(reportBuilder, valuesDict);

            var total = valuesDict.Values.Where(v => v > 0M).Sum();
            reportBuilder.AppendLine(string.Format("Portfolio: {0}", portfolio.Name));
            foreach (var category in categories)
            {
                Dictionary<string, decimal> calculations = new Dictionary<string, decimal>();

                foreach (var kvpair in valuesDict)
                {
                    var weight = weightsList.Single(w => w.Security.Symbol.Equals(kvpair.Key) && w.Value.Category == category);
                    if (calculations.ContainsKey(weight.Value.Name))
                        calculations[weight.Value.Name] += kvpair.Value;
                    else
                        calculations.Add(weight.Value.Name, kvpair.Value);
                }

                reportBuilder.AppendLine(string.Format("\r\n{0}", category.Name));
                foreach (var kvpair in calculations.OrderByDescending(kv => kv.Value))
                {
                    reportBuilder.AppendLine(String.Format("{0}: {1:N1}%", kvpair.Key, kvpair.Value / total * 100M));
                }
            }

            return reportBuilder.ToString();
        }