/// <summary>
        /// Similar to CalculateRangeRings, this is done with ABSOLUTE data, not detected values.
        /// This method is called in a ViewProAttributeUpdate call, which only contains attributes
        /// which have CHANGED, and will determine if either the sensors, vulnerabilties, or capabilities (including docked weapons) has
        /// changed.  If so, then new attributes will be added to the attribute collection value.
        /// </summary>
        /// <param name="acv"></param>
        /// <param name="fullObjectView"></param>
        /// <returns></returns>
        private void AddRangeRings(ref AttributeCollectionValue acv, ref SimulationObjectProxy fullObjectView)
        {
            if (acv.attributes.ContainsKey("Sensors"))
            {
                //detected contains a sensor array type
                CustomAttributesValue sensorCollection = DataValueFactory.BuildCustomAttributes(new Dictionary <string, DataValue>()) as CustomAttributesValue;
                RangeRingDisplayValue sensorRing;
                SensorArrayValue      detectedSensors = acv["Sensors"] as SensorArrayValue;

                foreach (SensorValue sv in detectedSensors.sensors)
                {
                    sensorRing = DataValueFactory.BuildRangeRingDisplayValue(sv.sensorName, "Sensors", false, new Dictionary <int, int>()) as RangeRingDisplayValue;
                    sensorRing.rangeIntensities.Add(Convert.ToInt32(sv.maxRange), -1);

                    sensorCollection.attributes.Add(sv.sensorName, sensorRing);
                }

                if (sensorCollection.attributes.Count > 0)
                {
                    acv.attributes.Add("SensorRangeRings", sensorCollection);
                }
                else
                {
                    Console.WriteLine("No SensorRangeRings added to ACV");
                }
            }
            if (acv.attributes.ContainsKey("Vulnerability"))
            {
                //gets detected values, containing a vulnerability type
                CustomAttributesValue    vulnerabilityCollection = DataValueFactory.BuildCustomAttributes(new Dictionary <string, DataValue>()) as CustomAttributesValue;
                RangeRingDisplayValue    vulnerabilityRing;
                VulnerabilityValue       detectedVulnerability = acv["Vulnerability"] as VulnerabilityValue;
                Dictionary <string, int> longestRange          = new Dictionary <string, int>();//[Capability],[Range]

                foreach (VulnerabilityValue.Transition tr in detectedVulnerability.transitions)
                {
                    foreach (VulnerabilityValue.TransitionCondition tc in tr.conditions)
                    {
                        if (!longestRange.ContainsKey(tc.capability))
                        {
                            longestRange.Add(tc.capability, -1);
                        }
                        if (longestRange[tc.capability] < Convert.ToInt32(tc.range))
                        {
                            longestRange[tc.capability] = Convert.ToInt32(tc.range);
                        }
                    }
                }

                foreach (KeyValuePair <string, int> kvp in longestRange)
                {
                    vulnerabilityRing = DataValueFactory.BuildRangeRingDisplayValue(kvp.Key, "Vulnerability", false, new Dictionary <int, int>()) as RangeRingDisplayValue;
                    vulnerabilityRing.rangeIntensities.Add(kvp.Value, -1);

                    vulnerabilityCollection.attributes.Add(kvp.Key, vulnerabilityRing);
                }


                if (vulnerabilityCollection.attributes.Count > 0)
                {
                    acv.attributes.Add("VulnerabilityRangeRings", vulnerabilityCollection);
                }
                else
                {
                    Console.WriteLine("No VulnerabilityRangeRings added to ACV");
                }
            }
            if (acv.attributes.ContainsKey("Capability") || acv.attributes.ContainsKey("DockedWeapons"))
            {
                CustomAttributesValue capabilityCollection = DataValueFactory.BuildCustomAttributes(new Dictionary <string, DataValue>()) as CustomAttributesValue;
                RangeRingDisplayValue capabilityRing;

                Dictionary <string, int> longestWeaponRange = new Dictionary <string, int>();//[Capability],[Range]


                //docked weapons gets string list of IDs
                if (acv.attributes.ContainsKey("DockedWeapons"))
                {
                    StringListValue dockedWeapons = acv["DockedWeapons"] as StringListValue;
                    foreach (String weaponID in dockedWeapons.strings)
                    {
                        //get weapon id
                        //get proxy info for weapon
                        SimulationObjectProxy weapon = objectProxies[weaponID];
                        string species = ((StringValue)weapon["ClassName"].GetDataValue()).value;
                        if (longestWeaponRange.ContainsKey(species))
                        {
                            continue;
                            //For now, assume that all weapons of the same species type have the same ranges.
                            //this will cut back on unneccessary loops, and for the most part is 100% true.
                        }

//get max speed, maxfuel or current fuel, get fuel consumption rate, get SHORTEST capability range
                        double maxSpeed             = ((DoubleValue)weapon["MaximumSpeed"].GetDataValue()).value;
                        double maxFuel              = ((DoubleValue)weapon["FuelCapacity"].GetDataValue()).value;
                        double fuelConsumptionRate  = ((DoubleValue)weapon["FuelConsumptionRate"].GetDataValue()).value;
                        double shortCapabilityRange = -1;

                        CapabilityValue             weaponCV  = (CapabilityValue)weapon["Capability"].GetDataValue();
                        Dictionary <string, double> capRanges = new Dictionary <string, double>();

                        foreach (CapabilityValue.Effect ef in weaponCV.effects)
                        {
                            if (!capRanges.ContainsKey(ef.name))
                            {
                                capRanges.Add(ef.name, ef.range);
                            }
                            else
                            {
                                if (capRanges[ef.name] > ef.range)
                                {//You want the smaller range here because that's how weapons work.  Auto-attacks use the SHORTEST range to trigger.
                                    capRanges[ef.name] = ef.range;
                                }
                            }
                        }
                        //but here, you want the LONGEST of the ranges that could trigger an auto-attack.
                        foreach (KeyValuePair <string, double> kvp in capRanges)
                        {
                            if (kvp.Value > shortCapabilityRange)
                            {
                                shortCapabilityRange = kvp.Value;
                            }
                        }

                        double thisRange = maxSpeed * maxFuel * fuelConsumptionRate + shortCapabilityRange;
                        longestWeaponRange.Add(species, Convert.ToInt32(thisRange));
                    }
                    //
                }

                Dictionary <string, Dictionary <double, double> > capabilityRanges = new Dictionary <string, Dictionary <double, double> >();
                if (acv.attributes.ContainsKey("Capability"))
                {
                    CapabilityValue detectedCapability = acv["Capability"] as CapabilityValue;


                    foreach (CapabilityValue.Effect ef in detectedCapability.effects)
                    {
                        if (!capabilityRanges.ContainsKey(ef.name))
                        {
                            capabilityRanges.Add(ef.name, new Dictionary <double, double>());
                        }

                        capabilityRanges[ef.name].Add(ef.range, ef.intensity);
                    }
                }

                //add all capabilities to ring collection
                foreach (string capName in capabilityRanges.Keys)
                {
                    if (!capabilityCollection.attributes.ContainsKey(capName))
                    {
                        capabilityRing = DataValueFactory.BuildRangeRingDisplayValue(capName, "Capability", false, new Dictionary <int, int>()) as RangeRingDisplayValue;
                        Dictionary <int, int> convertedRanges = new Dictionary <int, int>();
                        foreach (KeyValuePair <double, double> kvp in capabilityRanges[capName])
                        {
                            convertedRanges.Add(Convert.ToInt32(kvp.Key), Convert.ToInt32(kvp.Value));
                        }
                        capabilityRing.AddAndSortRanges(convertedRanges); //this sorts as well

                        capabilityCollection.attributes.Add(capName, capabilityRing);
                    }
                    else
                    {
                        Console.WriteLine("Failed to add duplicate capability to collection, {0}", capName);
                    }
                }

                foreach (string weaponSpeciesName in longestWeaponRange.Keys)
                {
                    if (!capabilityCollection.attributes.ContainsKey(weaponSpeciesName))
                    {
                        capabilityRing = DataValueFactory.BuildRangeRingDisplayValue(weaponSpeciesName, "Capability", true, new Dictionary <int, int>()) as RangeRingDisplayValue;
                        capabilityRing.rangeIntensities.Add(longestWeaponRange[weaponSpeciesName], -1); //TODO: Maybe add intensity above?
                        capabilityCollection.attributes.Add(weaponSpeciesName, capabilityRing);
                    }
                    else
                    {
                        Console.WriteLine("Failed to add duplicate capability(Weapon species) to collection, {0}", weaponSpeciesName);
                    }
                }

                if (capabilityCollection.attributes.Count > 0)
                {
                    acv.attributes.Add("CapabilityRangeRings", capabilityCollection);
                }
                else
                {
                    Console.WriteLine("No CapabilityRangeRings added to ACV");
                }
            }
        }