Repository: Azure/azure-sdk-for-net
File: eng/packages/http-client-csharp-mgmt/generator/Azure.Generator.Management/src/Visitors/InheritableSystemObjectModelVisitor.cs (C#)

Code before:
            {
                continue;
            }
            methods.Add(method);
        }
        modelFactory.Update(methods: methods);
    }

    private static void UpdateNamespace(InheritableSystemObjectModelProvider systemType)
    {
        // This is needed because we updated the namespace with NamespaceVisitor in Azure generator earlier
        systemType.Update(@namespace: systemType._type.Namespace);
    }

    private HashSet<ModelProvider> _updated = new();
    private HashSet<ModelProvider> _regularUpdated = new();
    private void Update(InheritableSystemObjectModelProvider baseSystemType, ModelProvider model)
    {
        // Add cache to avoid duplicated update of PreVisitModel and VisitType
        if (_updated.Contains(model))
        {
            return;
        }

        // Collect names of properties being removed to strip orphaned virtual from base
        var removedPropertyNames = new HashSet<string>(
            model.Properties
                .Where(prop => prop.Modifiers.HasFlag(MethodSignatureModifiers.New))
                .Select(prop => prop.Name));

        // If the model property modifiers contain 'new', we should drop it because the base type already has it.
        model.Update(properties: model.Properties.Where(prop => !prop.Modifiers.HasFlag(MethodSignatureModifiers.New)).ToArray());

        var rawDataField = CreateRawDataField(model);
        UpdateSerialization(model);

        UpdateFullConstructor(model, rawDataField);

        var baseSystemPropertyNames = EnumerateBaseModelProperties(baseSystemType);
        foreach (var prop in model.Properties.Where(prop => baseSystemPropertyNames.Contains(prop.Name)))
        {
            removedPropertyNames.Add(prop.Name);
        }
        var properties = model.Properties.Where(prop => !baseSystemPropertyNames.Contains(prop.Name));

        model.Update(properties: properties, fields: [.. model.Fields, rawDataField]);

        // Strip orphaned virtual modifiers from base properties that no longer have overrides
        StripOrphanedVirtualModifiers(baseSystemType, removedPropertyNames);

        _updated.Add(model);

Review comment (refactor):
can we extract this to a method, it is duplicated with L141.
And also, can we do this after baseSystemPropertyNames is constructed? so that, we can get this done together in a method to remove the duplicates

Code after:
        // Apply deferred serialization updates that were postponed from PreVisitModel
        // for discriminated models only (see comment in PreVisitModel).
        if (type is ModelProvider pendingModel && _pendingSerialization.Remove(pendingModel))
        {
            UpdateSerialization(pendingModel);
        }
        return type;
    }

    private static void UpdateModelFactory(ModelFactoryProvider modelFactory)
    {
        var methods = new List<MethodProvider>();
        foreach (var method in modelFactory.Methods)
        {
            var returnType = method.Signature.ReturnType;
            if (returnType is not null && KnownManagementTypes.IsKnownManagementType(returnType))
            {
                continue;
            }
            methods.Add(method);
        }
        modelFactory.Update(methods: methods);
    }

    private static void UpdateNamespace(InheritableSystemObjectModelProvider systemType)
    {
        // This is needed because we updated the namespace with NamespaceVisitor in Azure generator earlier
        systemType.Update(@namespace: systemType._type.Namespace);
    }

    private HashSet<ModelProvider> _updated = new();
    private HashSet<ModelProvider> _regularUpdated = new();
    private HashSet<ModelProvider> _pendingSerialization = new();
    private void Update(InheritableSystemObjectModelProvider baseSystemType, ModelProvider model, bool deferSerialization = false)
    {
        // Add cache to avoid duplicated update of PreVisitModel and VisitType
        if (_updated.Contains(model))
        {
            return;
        }

        // If the model property modifiers contain 'new', we should drop it because the base type already has it.
        // This must happen before UpdateFullConstructor to preserve constructor parameter ordering.
        model.Update(properties: model.Properties.Where(prop => !prop.Modifiers.HasFlag(MethodSignatureModifiers.New)).ToArray());

        var rawDataField = CreateRawDataField(model);

        // Update the full constructor before filtering properties to preserve the original parameter order.
        UpdateFullConstructor(model, rawDataField);

        // Filter out base class properties before accessing serialization methods.