internal static List<BondStructureCountryGroupCreator> GetXMktSpreads(IEnumerable<BondMarket> markets_, CountryGroupNodeMode mode_, int index_ = -1)
    {
      var ret = new List<BondStructureCountryGroupCreator>();

      var markets = markets_.ToArray();

      for (int i = 0; i < markets.Length; ++i)
        for (int j = i + 1; j < markets.Length; ++j)
        {
          // James needs to supply the order of convention to make this accurage
          var higherTenor = markets[i];
          var lowerTenor = markets[j];

          if (index_ == -1)
          {
            ret.AddRange(StructureConfigs.InterCountrySpreadPoints.Select(conf => new BondStructureCountryGroupCreator(new[]
            {
              new Tuple<int, BondMarket, double>(conf[0], higherTenor, StructureWeightings.Curve_Near), 
              new Tuple<int, BondMarket, double>(conf[0], lowerTenor, StructureWeightings.Curve_Far)
            }, mode_)));
          }
          else
          {
            ret.Add(new BondStructureCountryGroupCreator(new[]
              {
                new Tuple<int,BondMarket,double>(StructureConfigs.InterCountrySpreadPoints[index_][0],higherTenor,StructureWeightings.Curve_Near),
                new Tuple<int,BondMarket,double>(StructureConfigs.InterCountrySpreadPoints[index_][0],lowerTenor,StructureWeightings.Curve_Far)
              }, mode_));
          }
        }
      return ret;
    }
 public CountryGroupNode(string text_, BondMarket[] markets_, StructureGrouping grouping_, CountryGroupNodeMode mode_,  int structureIndex_=-1)
 {
   Markets = markets_;
   Text = text_;
   Grouping = grouping_;
   StructureIndex = structureIndex_;
   Mode = mode_;
 }
    internal static List<BondStructureCountryGroupCreator> GetOutrights(IEnumerable<BondMarket> markets_, CountryGroupNodeMode mode_, int index_ = -1)
    {
      if (index_ == -1)
        return (from mkt in markets_
                from tenor in CMTLine.DisplayPoints
                select new BondStructureCountryGroupCreator(new[]
        {
          new Tuple<int,BondMarket,double>((int)tenor,mkt, 1d) 
        }, mode_)).ToList();
      else
        return (from mkt in markets_
                select new BondStructureCountryGroupCreator(new[]
        {
          new Tuple<int,BondMarket,double>((int)CMTLine.DisplayPoints[index_],mkt, 1d) 
        }, mode_)).ToList();

    }
 internal static List<BondStructureCountryGroupCreator> GetButterflies(IEnumerable<BondMarket> markets_, CountryGroupNodeMode mode_, int index_ = -1)
 {
   if (index_ == -1)
     return (from mkt in markets_
             from conf in StructureConfigs.IntraCountryButterflies
             select new BondStructureCountryGroupCreator(new[]
     {
       new Tuple<int,BondMarket,double>( conf[0],mkt,StructureWeightings.Bfly_Wing) , 
       new Tuple<int,BondMarket,double>( conf[1],mkt,StructureWeightings.Bfly_Belly) , 
       new Tuple<int,BondMarket,double>( conf[2],mkt,StructureWeightings.Bfly_Wing) , 
     }, mode_)).ToList();
   else
     return (from mkt in markets_
             select new BondStructureCountryGroupCreator(new[]
     {
       new Tuple<int,BondMarket,double>( StructureConfigs.IntraCountryButterflies[index_][0],mkt,StructureWeightings.Bfly_Wing) , 
       new Tuple<int,BondMarket,double>( StructureConfigs.IntraCountryButterflies[index_][1],mkt,StructureWeightings.Bfly_Belly) , 
       new Tuple<int,BondMarket,double>( StructureConfigs.IntraCountryButterflies[index_][2],mkt,StructureWeightings.Bfly_Wing) , 
     }, mode_)).ToList();
 }
    private void addCountryStructures(string rootNodeText_, CountryGroupNodeMode mode_)
    {
      var otrTop = new CountryGroupNode(rootNodeText_, LiveMarkets.Markets,
        StructureGrouping.Outrights | StructureGrouping.Butterflies | StructureGrouping.Curves, mode_);
      otrTop.LeftImages.Add(BSAResources.folder_icon_16black);
      ultraTree1.Nodes.Add(otrTop);

      foreach (var market in LiveMarkets.Markets)
      {
        var marketNode = new CountryGroupNode(market.ToString(), new[] { market },
          StructureGrouping.Outrights | StructureGrouping.Butterflies | StructureGrouping.Curves, mode_);
        marketNode.LeftImages.Add(BSAResources.folder_icon_16black);
        otrTop.Nodes.Add(marketNode);


        foreach (var group in new[] { StructureGrouping.Outrights, StructureGrouping.Curves, StructureGrouping.Butterflies })
        {
          var marketGroupNode = new CountryGroupNode(group.ToString(), new[] { market }, group,mode_);
          marketGroupNode.LeftImages.Add(BSAResources.folder_arrow_icon_16);
          marketNode.Nodes.Add(marketGroupNode);
        }

        {
          var topXMarketNode = new CountryGroupNode("X-Mkt Spreads", new[] { BondMarket.None }, StructureGrouping.None, mode_);
          topXMarketNode.LeftImages.Add(BSAResources.globe_1_icon_16);
          marketNode.Nodes.Add(topXMarketNode);

          for (int i = 0; i < LiveMarkets.Markets.Length; ++i)
          {
            if (LiveMarkets.Markets[i] == market) continue;

            var xmktNode = new CountryGroupNode(string.Format("{0}.{1}", market, LiveMarkets.Markets[i]),
              new[] { market, LiveMarkets.Markets[i] }, StructureGrouping.XMarketSpreads, mode_);
            xmktNode.LeftImages.Add(BSAResources.globe_2_icon_16);
            topXMarketNode.Nodes.Add(xmktNode);
          }
        }

        {
          var topXMarketNode = new CountryGroupNode("X-Mkt Boxes", new[] { BondMarket.None }, StructureGrouping.None, mode_);
          topXMarketNode.LeftImages.Add(BSAResources.globe_1_icon_16);
          marketNode.Nodes.Add(topXMarketNode);

          for (int i = 0; i < LiveMarkets.Markets.Length; ++i)
          {
            if (LiveMarkets.Markets[i] == market) continue;

            var xmktNode = new CountryGroupNode(string.Format("{0}.{1}", market, LiveMarkets.Markets[i]),
              new[] { market, LiveMarkets.Markets[i] }, StructureGrouping.XMarketBoxes,mode_);
            xmktNode.LeftImages.Add(BSAResources.globe_2_icon_16);
            topXMarketNode.Nodes.Add(xmktNode);
          }
        }
      }

      // outrights
      {
        var outrightNode = new CountryGroupNode("Outrights", LiveMarkets.Markets, StructureGrouping.None, mode_, -1);
        outrightNode.LeftImages.Add(BSAResources.folder_icon_16black);
        otrTop.Nodes.Add(outrightNode);

        var allPoints = CMTLine.DisplayPoints;

        for (int index = 0; index < allPoints.Length; ++index)
        {
          var node = new CountryGroupNode(string.Format("{0}", allPoints[index]), LiveMarkets.Markets,
            StructureGrouping.Outrights, mode_, index);
          node.LeftImages.Add(BSAResources.folder_icon_16black);
          outrightNode.Nodes.Add(node);
        }
      }

      // curves
      {
        var curvesNode = new CountryGroupNode("Curves", LiveMarkets.Markets, StructureGrouping.None, mode_, -1);
        curvesNode.LeftImages.Add(BSAResources.folder_icon_16black);
        otrTop.Nodes.Add(curvesNode);

        var allPoints = StructureConfigs.IntraCountryCurves;

        for (int index = 0; index < allPoints.Count; ++index)
        {
          var node = new CountryGroupNode(string.Format("{0} {1}", allPoints[index][0], allPoints[index][1]), LiveMarkets.Markets,
            StructureGrouping.Curves, mode_, index);
          node.LeftImages.Add(BSAResources.folder_icon_16black);
          curvesNode.Nodes.Add(node);
        }
      }

      // butterflies
      {
        var bflyNode = new CountryGroupNode("Butterflies", LiveMarkets.Markets, StructureGrouping.None, mode_, -1);
        bflyNode.LeftImages.Add(BSAResources.folder_icon_16black);
        otrTop.Nodes.Add(bflyNode);

        var allPoints = StructureConfigs.IntraCountryButterflies;

        for (int index = 0; index < allPoints.Count; ++index)
        {
          var node = new CountryGroupNode(string.Format("{0} {1} {2}", allPoints[index][0], allPoints[index][1], allPoints[index][2]), LiveMarkets.Markets,
            StructureGrouping.Butterflies, mode_, index);
          node.LeftImages.Add(BSAResources.folder_icon_16black);
          bflyNode.Nodes.Add(node);
        }
      }

      // boxes
      {
        var boxesNode = new CountryGroupNode("Boxes", LiveMarkets.Markets, StructureGrouping.None, mode_, -1);
        boxesNode.LeftImages.Add(BSAResources.folder_icon_16black);
        otrTop.Nodes.Add(boxesNode);

        var allPoints = StructureConfigs.InterCountryBoxSides;
        for (int index = 0; index < allPoints.Count; ++index)
        {
          var node = new CountryGroupNode(string.Format("Boxes {0} {1}", allPoints[index][0], allPoints[index][1]),
            LiveMarkets.Markets, StructureGrouping.XMarketBoxes, mode_, index);
          node.LeftImages.Add(BSAResources.folder_icon_16black);
          boxesNode.Nodes.Add(node);
        }
      }

      ultraTree1.RefreshSort(otrTop.Nodes, true);
    }
    internal static List<BondStructureCountryGroupCreator> GetItems(BondMarket[] markets_, StructureGrouping grouping_, CountryGroupNodeMode mode_, int index_)
    {
      var list = new List<BondStructureCountryGroupCreator>();

      if (grouping_.Has(StructureGrouping.Outrights))
        list.AddRange(GetOutrights(markets_, mode_, index_));

      if (grouping_.Has(StructureGrouping.Curves))
        list.AddRange(GetCurves(markets_, mode_, index_));

      if (grouping_.Has(StructureGrouping.Butterflies))
        list.AddRange(GetButterflies(markets_, mode_, index_));

      if (grouping_.Has(StructureGrouping.XMarketSpreads))
        list.AddRange(GetXMktSpreads(markets_, mode_, index_));

      if (grouping_.Has(StructureGrouping.XMarketBoxes))
        list.AddRange(GetXMktBoxes(markets_, mode_, index_));

      return list;
    }
    internal static List<BondStructureCountryGroupCreator> GetXMktBoxes(IEnumerable<BondMarket> markets_, CountryGroupNodeMode mode_, int index_ = -1)
    {
      var ret = new List<BondStructureCountryGroupCreator>();

      var markets = markets_.ToArray();

      for (int i = 0; i < markets.Length; ++i)
        for (int j = i + 1; j < markets.Length; ++j)
        {
          var higherTenor = markets[i];
          var lowerTenor = markets[j];

          if (index_ == -1)
          {
            foreach (var conf in StructureConfigs.InterCountryBoxSides)
            {
              ret.Add(new BondStructureCountryGroupCreator(new[]
            {
              new Tuple<int, BondMarket, double>(conf[0], lowerTenor, StructureWeightings.Box_1),
              new Tuple<int, BondMarket, double>(conf[1], lowerTenor, StructureWeightings.Box_2),
              new Tuple<int, BondMarket, double>(conf[0], higherTenor, StructureWeightings.Box_3),
              new Tuple<int, BondMarket, double>(conf[1], higherTenor, StructureWeightings.Box_4),
            }, mode_));
            }
          }
          else
          {
            ret.Add(new BondStructureCountryGroupCreator(new[]
            {
              new Tuple<int, BondMarket, double>(StructureConfigs.InterCountryBoxSides[index_][0], lowerTenor, StructureWeightings.Box_1),
              new Tuple<int, BondMarket, double>(StructureConfigs.InterCountryBoxSides[index_][1], lowerTenor, StructureWeightings.Box_2),
              new Tuple<int, BondMarket, double>(StructureConfigs.InterCountryBoxSides[index_][0], higherTenor, StructureWeightings.Box_3),
              new Tuple<int, BondMarket, double>(StructureConfigs.InterCountryBoxSides[index_][1], higherTenor, StructureWeightings.Box_4),
            }, mode_));

          }
        }

      return ret;
    }
 public BondStructureCountryGroupCreator(Tuple<int, BondMarket, double>[] points_, CountryGroupNodeMode mode_)
 {
   Points = points_;
   Mode = mode_;
 }