How to use Generate method of Telerik.JustMock.Core.Castle.DynamicProxy.Contributors.ClassProxyInstanceContributor class

Best JustMockLite code snippet using Telerik.JustMock.Core.Castle.DynamicProxy.Contributors.ClassProxyInstanceContributor.Generate

ClassProxyInstanceContributor.cs

Source:ClassProxyInstanceContributor.cs Github

copy

Full Screen

...47 protected override Reference GetTargetReference(ClassEmitter emitter)48 {49 return SelfReference.Self;50 }51 public override void Generate(ClassEmitter @class, ProxyGenerationOptions options)52 {53 var interceptors = @class.GetField("__interceptors");54#if FEATURE_SERIALIZATION55 if (implementISerializable)56 {57 ImplementGetObjectData(@class);58 Constructor(@class);59 }60#endif61 ImplementProxyTargetAccessor(@class, interceptors);62 foreach (var attribute in targetType.GetTypeInfo().GetNonInheritableAttributes())63 {64 @class.DefineCustomAttribute(attribute.Builder);65 }66 }67#if FEATURE_SERIALIZATION68 protected override void AddAddValueInvocation(ArgumentReference serializationInfo, MethodEmitter getObjectData,69 FieldReference field)70 {71 serializedFields.Add(field);72 base.AddAddValueInvocation(serializationInfo, getObjectData, field);73 }74 protected override void CustomizeGetObjectData(AbstractCodeBuilder codebuilder, ArgumentReference serializationInfo,75 ArgumentReference streamingContext, ClassEmitter emitter)76 {77 codebuilder.AddStatement(new ExpressionStatement(78 new MethodInvocationExpression(79 serializationInfo,80 SerializationInfoMethods.AddValue_Bool,81 new ConstReference("__delegateToBase").ToExpression(),82 new ConstReference(delegateToBaseGetObjectData).83 ToExpression())));84 if (delegateToBaseGetObjectData == false)85 {86 EmitCustomGetObjectData(codebuilder, serializationInfo);87 return;88 }89 EmitCallToBaseGetObjectData(codebuilder, serializationInfo, streamingContext);90 }91 private void EmitCustomGetObjectData(AbstractCodeBuilder codebuilder, ArgumentReference serializationInfo)92 {93 var members = codebuilder.DeclareLocal(typeof(MemberInfo[]));94 var data = codebuilder.DeclareLocal(typeof(object[]));95 var getSerializableMembers = new MethodInvocationExpression(96 null,97 FormatterServicesMethods.GetSerializableMembers,98 new TypeTokenExpression(targetType));99 codebuilder.AddStatement(new AssignStatement(members, getSerializableMembers));100 // Sort to keep order on both serialize and deserialize side the same, c.f DYNPROXY-ISSUE-127101 var callSort = new MethodInvocationExpression(102 null,103 TypeUtilMethods.Sort,104 members.ToExpression());105 codebuilder.AddStatement(new AssignStatement(members, callSort));106 var getObjectData = new MethodInvocationExpression(107 null,108 FormatterServicesMethods.GetObjectData,109 SelfReference.Self.ToExpression(),110 members.ToExpression());111 codebuilder.AddStatement(new AssignStatement(data, getObjectData));112 var addValue = new MethodInvocationExpression(113 serializationInfo,114 SerializationInfoMethods.AddValue_Object,115 new ConstReference("__data").ToExpression(),116 data.ToExpression());117 codebuilder.AddStatement(new ExpressionStatement(addValue));118 }119 private void EmitCallToBaseGetObjectData(AbstractCodeBuilder codebuilder, ArgumentReference serializationInfo,120 ArgumentReference streamingContext)121 {122 var baseGetObjectData = targetType.GetMethod("GetObjectData",123 new[] { typeof(SerializationInfo), typeof(StreamingContext) });124 codebuilder.AddStatement(new ExpressionStatement(125 new MethodInvocationExpression(baseGetObjectData,126 serializationInfo.ToExpression(),127 streamingContext.ToExpression())));128 }129 private void Constructor(ClassEmitter emitter)130 {131 if (!delegateToBaseGetObjectData)132 {133 return;134 }135 GenerateSerializationConstructor(emitter);136 }137 private void GenerateSerializationConstructor(ClassEmitter emitter)138 {139 var serializationInfo = new ArgumentReference(typeof(SerializationInfo));140 var streamingContext = new ArgumentReference(typeof(StreamingContext));141 var ctor = emitter.CreateConstructor(serializationInfo, streamingContext);142 ctor.CodeBuilder.AddStatement(143 new ConstructorInvocationStatement(serializationConstructor,144 serializationInfo.ToExpression(),145 streamingContext.ToExpression()));146 foreach (var field in serializedFields)147 {148 var getValue = new MethodInvocationExpression(serializationInfo,149 SerializationInfoMethods.GetValue,150 new ConstReference(field.Reference.Name).ToExpression(),151 new TypeTokenExpression(field.Reference.FieldType));...

Full Screen

Full Screen

ClassProxyGenerator.cs

Source:ClassProxyGenerator.cs Github

copy

Full Screen

...28 {29 CheckNotGenericTypeDefinition(targetType, "targetType");30 EnsureDoesNotImplementIProxyTargetAccessor(targetType, "targetType");31 }32 public Type GenerateCode(Type[] interfaces, ProxyGenerationOptions options)33 {34 // make sure ProxyGenerationOptions is initialized35 options.Initialize();36 interfaces = TypeUtil.GetAllInterfaces(interfaces);37 CheckNotGenericTypeDefinitions(interfaces, "interfaces");38 ProxyGenerationOptions = options;39 var cacheKey = new CacheKey(targetType, interfaces, options);40 return ObtainProxyType(cacheKey, (n, s) => GenerateType(n, interfaces, s));41 }42 protected virtual Type GenerateType(string name, Type[] interfaces, INamingScope namingScope)43 {44 IEnumerable<ITypeContributor> contributors;45 var implementedInterfaces = GetTypeImplementerMapping(interfaces, out contributors, namingScope);46 var model = new MetaType();47 // Collect methods48 foreach (var contributor in contributors)49 {50 contributor.CollectElementsToProxy(ProxyGenerationOptions.Hook, model);51 }52 ProxyGenerationOptions.Hook.MethodsInspected();53 var emitter = BuildClassEmitter(name, targetType, implementedInterfaces);54 CreateFields(emitter);55 CreateTypeAttributes(emitter);56 // Constructor57 var cctor = GenerateStaticConstructor(emitter);58 var constructorArguments = new List<FieldReference>();59 foreach (var contributor in contributors)60 {61 contributor.Generate(emitter, ProxyGenerationOptions);62 // TODO: redo it63 var mixinContributor = contributor as MixinContributor;64 if (mixinContributor != null)65 {66 constructorArguments.AddRange(mixinContributor.Fields);67 }68 }69 // constructor arguments70 var interceptorsField = emitter.GetField("__interceptors");71 constructorArguments.Add(interceptorsField);72 var selector = emitter.GetField("__selector");73 if (selector != null)74 {75 constructorArguments.Add(selector);76 }77 GenerateConstructors(emitter, targetType, constructorArguments.ToArray());78 GenerateParameterlessConstructor(emitter, targetType, interceptorsField);79 // Complete type initializer code body80 CompleteInitCacheMethod(cctor.CodeBuilder);81 // Crosses fingers and build type82 Type proxyType = emitter.BuildType();83 InitializeStaticFields(proxyType);84 return proxyType;85 }86 protected virtual IEnumerable<Type> GetTypeImplementerMapping(Type[] interfaces,87 out IEnumerable<ITypeContributor> contributors,88 INamingScope namingScope)89 {90 var methodsToSkip = new List<MethodInfo>();91 var proxyInstance = new ClassProxyInstanceContributor(targetType, methodsToSkip, interfaces, ProxyTypeConstants.Class);92 // TODO: the trick with methodsToSkip is not very nice......

Full Screen

Full Screen

DelegateProxyGenerator.cs

Source:DelegateProxyGenerator.cs Github

copy

Full Screen

...32 }33 public Type GetProxyType()34 {35 var cacheKey = new CacheKey(targetType, null, null);36 return ObtainProxyType(cacheKey, GenerateType);37 }38 protected virtual IEnumerable<Type> GetTypeImplementerMapping(out IEnumerable<ITypeContributor> contributors,39 INamingScope namingScope)40 {41 var methodsToSkip = new List<MethodInfo>();42 var proxyInstance = new ClassProxyInstanceContributor(targetType, methodsToSkip, Type.EmptyTypes,43 ProxyTypeConstants.ClassWithTarget);44 var proxyTarget = new DelegateProxyTargetContributor(targetType, namingScope) { Logger = Logger };45 IDictionary<Type, ITypeContributor> typeImplementerMapping = new Dictionary<Type, ITypeContributor>();46 // Order of interface precedence:47 // 1. first target, target is not an interface so we do nothing48 // 2. then mixins - we support none so we do nothing49 // 3. then additional interfaces - we support none so we do nothing50 // 4. plus special interfaces51#if FEATURE_SERIALIZATION52 if (targetType.IsSerializable)53 {54 AddMappingForISerializable(typeImplementerMapping, proxyInstance);55 }56#endif57 AddMappingNoCheck(typeof(IProxyTargetAccessor), proxyInstance, typeImplementerMapping);58 contributors = new List<ITypeContributor>59 {60 proxyTarget,61 proxyInstance62 };63 return typeImplementerMapping.Keys;64 }65 private FieldReference CreateTargetField(ClassEmitter emitter)66 {67 var targetField = emitter.CreateField("__target", targetType);68#if FEATURE_SERIALIZATION69 emitter.DefineCustomAttributeFor<XmlIgnoreAttribute>(targetField);70#endif71 return targetField;72 }73 private Type GenerateType(string name, INamingScope namingScope)74 {75 IEnumerable<ITypeContributor> contributors;76 var implementedInterfaces = GetTypeImplementerMapping(out contributors, namingScope);77 var model = new MetaType();78 // Collect methods79 foreach (var contributor in contributors)80 {81 contributor.CollectElementsToProxy(ProxyGenerationOptions.Hook, model);82 }83 ProxyGenerationOptions.Hook.MethodsInspected();84 var emitter = BuildClassEmitter(name, typeof(object), implementedInterfaces);85 CreateFields(emitter);86 CreateTypeAttributes(emitter);87 // Constructor88 var cctor = GenerateStaticConstructor(emitter);89 var targetField = CreateTargetField(emitter);90 var constructorArguments = new List<FieldReference> { targetField };91 foreach (var contributor in contributors)92 {93 contributor.Generate(emitter, ProxyGenerationOptions);94 }95 // constructor arguments96 var interceptorsField = emitter.GetField("__interceptors");97 constructorArguments.Add(interceptorsField);98 var selector = emitter.GetField("__selector");99 if (selector != null)100 {101 constructorArguments.Add(selector);102 }103 GenerateConstructor(emitter, null, constructorArguments.ToArray());104 GenerateParameterlessConstructor(emitter, targetType, interceptorsField);105 // Complete type initializer code body106 CompleteInitCacheMethod(cctor.CodeBuilder);107 // Crosses fingers and build type108 var proxyType = emitter.BuildType();109 InitializeStaticFields(proxyType);110 return proxyType;111 }112 }113}...

Full Screen

Full Screen

Generate

Using AI Code Generation

copy

Full Screen

1using Telerik.JustMock;2using Telerik.JustMock.Core;3using Telerik.JustMock.Core.Castle.DynamicProxy;4using Telerik.JustMock.Core.Castle.DynamicProxy.Contributors;5using Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters.SimpleAST;6using System;7using System.Collections.Generic;8using System.Linq;9using System.Text;10using System.Threading.Tasks;11{12 {13 static void Main(string[] args)14 {15 var mock = Mock.Create<TestClass>();16 var proxy = Mock.GetMock(mock).Proxy;17 var contributor = new ClassProxyInstanceContributor(typeof(TestClass), proxy);18 var generator = new ProxyGenerator();19 var moduleScope = new ModuleScope(true);20 var emitter = new ClassEmitter(moduleScope, "TestClassProxy", typeof(TestClass), Type.EmptyTypes, TypeAttributes.Public);21 var method = typeof(ClassProxyInstanceContributor).GetMethod("Generate", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);22 method.Invoke(contributor, new object[] { generator, emitter });23 var type = emitter.BuildType();24 var instance = Activator.CreateInstance(type);25 var testClass = instance as TestClass;26 testClass.DoSomething();27 }28 }29 {30 public virtual void DoSomething()31 {32 Console.WriteLine("DoSomething");33 }34 }35}36using Telerik.JustMock;37using Telerik.JustMock.Core;38using Telerik.JustMock.Core.Castle.DynamicProxy;39using Telerik.JustMock.Core.Castle.DynamicProxy.Contributors;40using Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters.SimpleAST;41using System;42using System.Collections.Generic;43using System.Linq;44using System.Text;45using System.Threading.Tasks;46{47 {48 static void Main(string[] args)49 {50 var proxy = new InterfaceProxyWithoutTargetContributor(typeof(ITestClass));51 var generator = new ProxyGenerator();52 var moduleScope = new ModuleScope(true);53 var emitter = new ClassEmitter(moduleScope, "TestClassProxy", typeof(ITestClass), Type.EmptyTypes, TypeAttributes.Public);54 var method = typeof(InterfaceProxyWithoutTargetContributor).GetMethod

Full Screen

Full Screen

Generate

Using AI Code Generation

copy

Full Screen

1using Telerik.JustMock.Core.Castle.DynamicProxy.Contributors;2using Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters.SimpleAST;3using Telerik.JustMock.Core.Castle.DynamicProxy.Tokens;4using Telerik.JustMock.Core.Castle.DynamicProxy.Generators;5using Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters;6using Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters.SimpleAST;7using System.Reflection.Emit;8using System.Reflection;9using System;10using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder.SimpleAST;11using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder.Utils;12using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder;13using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder.SimpleAST;14using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder.Utils;15using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder;16using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder.SimpleAST;17using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder.Utils;18using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder;19using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder.SimpleAST;20using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder.Utils;21using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder;22using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder.SimpleAST;23using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder.Utils;24using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder;25using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder.SimpleAST;26using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder.Utils;27using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder;28using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder.SimpleAST;29using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder.Utils;30using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder;31using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder.SimpleAST;32using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder.Utils;33using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder;34using Telerik.JustMock.Core.Castle.DynamicProxy.Builder.CodeBuilder.SimpleAST;

Full Screen

Full Screen

Generate

Using AI Code Generation

copy

Full Screen

1using System;2using System.Collections.Generic;3using System.Linq;4using System.Text;5using System.Threading.Tasks;6using Telerik.JustMock.Core.Castle.DynamicProxy.Contributors;7{8 {9 static void Main(string[] args)10 {11 var classProxyInstanceContributor = new ClassProxyInstanceContributor();12 var type = classProxyInstanceContributor.Generate(typeof(IInterface1));13 }14 }15}16using System;17using System.Collections.Generic;18using System.Linq;19using System.Text;20using System.Threading.Tasks;21using Telerik.JustMock.Core.Castle.DynamicProxy.Contributors;22{23 {24 static void Main(string[] args)25 {26 var interfaceProxyInstanceContributor = new InterfaceProxyInstanceContributor();27 var type = interfaceProxyInstanceContributor.Generate(typeof(IInterface1));28 }29 }30}31using System;32using System.Collections.Generic;33using System.Linq;34using System.Text;35using System.Threading.Tasks;36using Telerik.JustMock.Core.Castle.DynamicProxy.Contributors;37{38 {39 static void Main(string[] args)40 {41 var interfaceProxyWithTargetInstanceContributor = new InterfaceProxyWithTargetInstanceContributor();42 var type = interfaceProxyWithTargetInstanceContributor.Generate(typeof(IInterface1), typeof(Class1));43 }44 }45}46using System;47using System.Collections.Generic;48using System.Linq;49using System.Text;50using System.Threading.Tasks;51using Telerik.JustMock.Core.Castle.DynamicProxy.Contributors;52{53 {54 static void Main(string[] args)55 {56 var mixinInstanceContributor = new MixinInstanceContributor();57 var type = mixinInstanceContributor.Generate(typeof(IInterface1));58 }59 }60}

Full Screen

Full Screen

Generate

Using AI Code Generation

copy

Full Screen

1var classProxyInstanceContributor = new Telerik.JustMock.Core.Castle.DynamicProxy.Contributors.ClassProxyInstanceContributor(typeof(1));2var generatorContext = new Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters.SimpleAST.GeneratorContext(new Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters.CodeBuilders.CodeBuilder());3var generator = new Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters.CodeBuilders.MethodCodeBuilder(generatorContext, typeof(1), new Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters.CodeBuilders.CodeBuilder());4classProxyInstanceContributor.Generate(generator);5var interfaceProxyWithTargetInstanceContributor = new Telerik.JustMock.Core.Castle.DynamicProxy.Contributors.InterfaceProxyWithTargetInstanceContributor(typeof(1));6var generatorContext = new Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters.SimpleAST.GeneratorContext(new Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters.CodeBuilders.CodeBuilder());7var generator = new Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters.CodeBuilders.MethodCodeBuilder(generatorContext, typeof(1), new Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters.CodeBuilders.CodeBuilder());8interfaceProxyWithTargetInstanceContributor.Generate(generator);9var interfaceProxyWithoutTargetInstanceContributor = new Telerik.JustMock.Core.Castle.DynamicProxy.Contributors.InterfaceProxyWithoutTargetInstanceContributor(typeof(1));10var generatorContext = new Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters.SimpleAST.GeneratorContext(new Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters.CodeBuilders.CodeBuilder());11var generator = new Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters.CodeBuilders.MethodCodeBuilder(generatorContext, typeof(1), new Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters.CodeBuilders.CodeBuilder());12interfaceProxyWithoutTargetInstanceContributor.Generate(generator);

Full Screen

Full Screen

Generate

Using AI Code Generation

copy

Full Screen

1using System;2using System.Collections.Generic;3using System.Linq;4using System.Text;5using System.Threading.Tasks;6using Telerik.JustMock.Core.Castle.DynamicProxy;7using Telerik.JustMock.Core.Castle.DynamicProxy.Contributors;8using Telerik.JustMock.Core.Castle.DynamicProxy.Generators;9using Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters;10using Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters.SimpleAST;11using Telerik.JustMock.Core.Castle.DynamicProxy.Generators.Emitters.CodeBuilders.SimpleAST;12{13 {14 static void Main(string[] args)15 {16 ModuleScope scope = new ModuleScope(true);17 ClassProxyInstanceContributor contributor = new ClassProxyInstanceContributor(typeof(ProxyClass), scope, new Type[] { typeof(IProxy) });18 Type type = contributor.Generate();19 }20 }21 {22 public virtual string Method(string input)23 {24 return input;25 }26 }27 {28 string Method(string input);29 }30}

Full Screen

Full Screen

Generate

Using AI Code Generation

copy

Full Screen

1var mock = Mock.Create<IFoo>();2Mock.Arrange(() => mock.Generate()).Returns("Hello World");3var mock = Mock.Create<IFoo>();4Mock.Arrange(() => mock.Generate()).Returns("Hello World");5var mock = Mock.Create<IFoo>();6Mock.Arrange(() => mock.Generate()).Returns("Hello World");7var mock = Mock.Create<IFoo>();8Mock.Arrange(() => mock.Generate()).Returns("Hello World");9var mock = Mock.Create<IFoo>();10Mock.Arrange(() => mock.Generate()).Returns("Hello World");11var mock = Mock.Create<IFoo>();12Mock.Arrange(() => mock.Generate()).Returns("Hello World");13var mock = Mock.Create<IFoo>();14Mock.Arrange(() => mock.Generate()).Returns("Hello World");15var mock = Mock.Create<IFoo>();16Mock.Arrange(() => mock.Generate()).Returns("Hello World");17var mock = Mock.Create<IFoo>();18Mock.Arrange(() => mock.Generate()).Returns("Hello World");

Full Screen

Full Screen

Generate

Using AI Code Generation

copy

Full Screen

1var type = new Telerik.JustMock.Core.Castle.DynamicProxy.Contributors.ClassProxyInstanceContributor(typeof(1), typeof(object), new Telerik.JustMock.Core.Castle.DynamicProxy.ProxyGenerationOptions()).Generate();2var instance = new Telerik.JustMock.Core.Castle.DynamicProxy.ProxyGenerator().CreateClassProxy(type);3var method = type.GetMethod("DoSomething");4method.Invoke(instance, null);5var type = new Telerik.JustMock.Core.Castle.DynamicProxy.Contributors.ClassProxyInstanceContributor(typeof(1), typeof(object), new Telerik.JustMock.Core.Castle.DynamicProxy.ProxyGenerationOptions()).Generate();6var instance = new Telerik.JustMock.Core.Castle.DynamicProxy.ProxyGenerator().CreateClassProxy(type);

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful