public static void ToGdbObjectMsgList(
            [NotNull] IEnumerable <Feature> features,
            [NotNull] ICollection <GdbObjectMsg> resultGdbObjects,
            [NotNull] ICollection <ObjectClassMsg> resultGdbClasses)
        {
            Stopwatch watch = null;

            if (_msg.IsVerboseDebugEnabled)
            {
                watch = Stopwatch.StartNew();
            }

            var classesByClassId = new Dictionary <long, FeatureClass>();

            // Optimization (in Pro, the Map SR seems to be generally equal to the FCs SR, if they match)
            bool omitDetailedShapeSpatialRef = true;

            foreach (Feature feature in features)
            {
                FeatureClass featureClass = feature.GetTable();

                Geometry shape = feature.GetShape();

                // NOTE: The following calls are expensive:
                // - Geometry.GetShape() (internally, the feature's spatial creation seems costly)
                // - FeatureClassDefintion.GetSpatialReference()
                // In case of a large feature count, they should be avoided on a per-feature basis:

                if (!classesByClassId.ContainsKey(featureClass.GetID()))
                {
                    resultGdbClasses.Add(ToObjectClassMsg(featureClass));

                    classesByClassId.Add(featureClass.GetID(), featureClass);

                    SpatialReference featureClassSpatialRef =
                        featureClass.GetDefinition().GetSpatialReference();

                    if (!SpatialReference.AreEqual(
                            featureClassSpatialRef, shape.SpatialReference, false, true))
                    {
                        omitDetailedShapeSpatialRef = false;
                    }
                }
                else
                {
                    // TODO: Better solution: hash class ID with workspace handle in ToObjectClassMsg()
                    // Make sure they are from the same workspace to avoid conflicting class ids
                    Assert.AreEqual(classesByClassId[featureClass.GetID()].GetDatastore().Handle,
                                    featureClass.GetDatastore().Handle,
                                    "Conflicting class id from different workspaces. Please report.");
                }

                resultGdbObjects.Add(ToGdbObjectMsg(feature, shape, omitDetailedShapeSpatialRef));
            }

            _msg.DebugStopTiming(watch, "Converted {0} features to DTOs", resultGdbObjects.Count);
        }