blob: 0d5ce1016e574f1bb024a0bc4ca75f4776829531 [file] [log] [blame]
Stephan Herrmann7b7062f2010-04-01 19:56:59 +00001/**********************************************************************
2 * This file is part of "Object Teams Development Tooling"-Software
Stephan Herrmannab1b9762010-09-26 14:31:00 +00003 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +00004 * Copyright 2004, 2006 Fraunhofer Gesellschaft, Munich, Germany,
5 * for its Fraunhofer Institute for Computer Architecture and Software
6 * Technology (FIRST), Berlin, Germany and Technical University Berlin,
7 * Germany.
Stephan Herrmannab1b9762010-09-26 14:31:00 +00008 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +00009 * All rights reserved. This program and the accompanying materials
10 * are made available under the terms of the Eclipse Public License v1.0
11 * which accompanies this distribution, and is available at
12 * http://www.eclipse.org/legal/epl-v10.html
13 * $Id: CalloutMappingDeclaration.java 23416 2010-02-03 19:59:31Z stephan $
Stephan Herrmannab1b9762010-09-26 14:31:00 +000014 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000015 * Please visit http://www.eclipse.org/objectteams for updates and contact.
Stephan Herrmannab1b9762010-09-26 14:31:00 +000016 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000017 * Contributors:
18 * Fraunhofer FIRST - Initial API and implementation
19 * Technical University Berlin - Initial API and implementation
20 **********************************************************************/
21package org.eclipse.jdt.core.dom;
22
23import java.util.ArrayList;
24import java.util.List;
25
26/**
27 * NEW for OTDT
Stephan Herrmannab1b9762010-09-26 14:31:00 +000028 *
29 * Represents DOM-ASTNode for Callout Bindings (OTJLD ยง2.4.2),
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000030 * which has to handle code from e.g. :
31 * foo => bar;
32 * to e.g. :
Stephan Herrmannab1b9762010-09-26 14:31:00 +000033 * Integer absoluteValue(Integer integer) -> int abs(int i) with {
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000034 * integer.intValue() -> i,
35 * result <- new Integer(result)
36 * }
37 * and also the callout to field binding:
38 * - without value mapping:
Stephan Herrmannab1b9762010-09-26 14:31:00 +000039 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000040 * setValue -> set value;
Stephan Herrmannab1b9762010-09-26 14:31:00 +000041 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000042 * int getValue() -> get int value;
Stephan Herrmannab1b9762010-09-26 14:31:00 +000043 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000044 * - with value mappings:
Stephan Herrmannab1b9762010-09-26 14:31:00 +000045 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000046 * Integer getValue() -> get int val
47 * with { result <- new Integer(result) }
Stephan Herrmannab1b9762010-09-26 14:31:00 +000048 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000049 * void setValue(Integer i) -> set int val
50 * with { integer.intValue() -> val }
51 *
Stephan Herrmannab1b9762010-09-26 14:31:00 +000052 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000053 * This class consists of one MethodSpec for bound role method and one MethodSpec for base method
54 * or FieldAccessSpec for access to a field of the base class. Also it consists of
55 * a callout kind and an optionally mapping of parameters.
Stephan Herrmannab1b9762010-09-26 14:31:00 +000056 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000057 * This node is used in TypeDeclaration, particulary in RoleTypeDeclaration.
Stephan Herrmannab1b9762010-09-26 14:31:00 +000058 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000059 * @author ike
60 */
61public class CalloutMappingDeclaration extends AbstractMethodMappingDeclaration
62{
63 public static final String CALLOUT = "->"; //$NON-NLS-1$
64 public static final String CALLOUT_OVERRIDE = "=>"; //$NON-NLS-1$
Stephan Herrmannab1b9762010-09-26 14:31:00 +000065
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000066 /**
Stephan Herrmannab1b9762010-09-26 14:31:00 +000067 * Creates a new AST node for a callout mapping declaration owned
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000068 * by the given AST. By default, the declaration is for a callout mapping
69 * of an unspecified, but legal, name;
70 * <p>
Stephan Herrmannab1b9762010-09-26 14:31:00 +000071 * N.B. This constructor is package-private; all subclasses must be
72 * declared in the same package; clients are unable to declare
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000073 * additional subclasses.
74 * </p>
Stephan Herrmannab1b9762010-09-26 14:31:00 +000075 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000076 * @param ast the AST that is to own this node
Stephan Herrmannab1b9762010-09-26 14:31:00 +000077 */
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000078 CalloutMappingDeclaration(AST ast)
79 {
80 super(ast);
81 }
82
83 /**
84 * The "javadoc" structural property of this node type.
85 */
Stephan Herrmannab1b9762010-09-26 14:31:00 +000086 public static final ChildPropertyDescriptor JAVADOC_PROPERTY =
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000087 internalJavadocPropertyFactory(CalloutMappingDeclaration.class);
Stephan Herrmannab1b9762010-09-26 14:31:00 +000088
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000089 /**
90 * The left "methodSpec" structural property of this node type.
91 */
Stephan Herrmannab1b9762010-09-26 14:31:00 +000092 public static final ChildPropertyDescriptor ROLE_MAPPING_ELEMENT_PROPERTY =
Stephan Herrmann7b7062f2010-04-01 19:56:59 +000093 new ChildPropertyDescriptor(CalloutMappingDeclaration.class, "roleMappingElement", MethodMappingElement.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
94
95 /**
96 * The binding operator structural property ("<- modifier")
97 * @since 1.3.1
98 */
99 public static final ChildPropertyDescriptor BINDING_OPERATOR_PROPERTY =
100 new ChildPropertyDescriptor(CalloutMappingDeclaration.class, "bindingOperator", MethodBindingOperator.class, MANDATORY, NO_CYCLE_RISK);
101
102 /**
103 * The right "methodSpec" structural property of this node type.
104 */
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000105 public static final ChildPropertyDescriptor BASE_MAPPING_ELEMENT_PROPERTY =
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000106 new ChildPropertyDescriptor(CalloutMappingDeclaration.class, "baseMappingElement", MethodMappingElement.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000107
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000108 /**
109 * The "signature" structural property of this node type.
110 */
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000111 public static final SimplePropertyDescriptor SIGNATURE_PROPERTY =
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000112 new SimplePropertyDescriptor(CalloutMappingDeclaration.class, "signature", boolean.class, MANDATORY); //$NON-NLS-1$
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000113
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000114 /**
115 * The "parameterMappings" structural property of this node type.
116 */
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000117 public static final ChildListPropertyDescriptor PARAMETER_MAPPINGS_PROPERTY =
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000118 internalParameterMappingPropertyFactory(CalloutMappingDeclaration.class);
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000119
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000120 /**
121 * The "modifiers" structural property of this node type.
122 */
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000123 public static final SimplePropertyDescriptor MODIFIERS_PROPERTY =
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000124 internalModifiersPropertyFactory(CalloutMappingDeclaration.class);
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000125
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000126 /**
127 * The "modifiers2" structural property of this node type.
128 */
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000129 public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY =
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000130 internalModifiers2PropertyFactory(CalloutMappingDeclaration.class);
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000131
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000132 /**
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000133 * A list of property descriptors (element type:
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000134 * {@link StructuralPropertyDescriptor}),
135 * or null if uninitialized.
136 */
137 private static final List PROPERTY_DESCRIPTORS_2_0;
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000138
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000139 /**
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000140 * A list of property descriptors (element type:
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000141 * {@link StructuralPropertyDescriptor}),
142 * or null if uninitialized.
143 */
144
145 private static final List PROPERTY_DESCRIPTORS_3_0;
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000146
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000147 private MethodMappingElement _baseMappingElement = null;
148 private boolean _baseMappingInitialized= false;
149 private boolean _hasSignature = false;
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000150
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000151 static
152 {
153 List propertyList = new ArrayList(8);
154 createPropertyList(CalloutMappingDeclaration.class, propertyList);
155 addProperty(JAVADOC_PROPERTY, propertyList);
156 addProperty(ROLE_MAPPING_ELEMENT_PROPERTY, propertyList);
157 addProperty(BINDING_OPERATOR_PROPERTY, propertyList);
158 addProperty(BASE_MAPPING_ELEMENT_PROPERTY, propertyList);
159 addProperty(SIGNATURE_PROPERTY, propertyList);
160 addProperty(PARAMETER_MAPPINGS_PROPERTY, propertyList);
161 addProperty(MODIFIERS_PROPERTY, propertyList);
162 PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList);
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000163
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000164 propertyList = new ArrayList(8);
165 createPropertyList(CalloutMappingDeclaration.class, propertyList);
166 addProperty(JAVADOC_PROPERTY, propertyList);
167 addProperty(ROLE_MAPPING_ELEMENT_PROPERTY, propertyList);
168 addProperty(BINDING_OPERATOR_PROPERTY, propertyList);
169 addProperty(BASE_MAPPING_ELEMENT_PROPERTY, propertyList);
170 addProperty(SIGNATURE_PROPERTY, propertyList);
171 addProperty(PARAMETER_MAPPINGS_PROPERTY, propertyList);
172 addProperty(MODIFIERS2_PROPERTY, propertyList);
173 PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList);
174 }
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000175
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000176 /**
177 * Returns a list of structural property descriptors for this node type.
178 * Clients must not modify the result.
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000179 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000180 * @param apiLevel the API level; one of the AST.JLS* constants
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000181 * @return a list of property descriptors (element type:
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000182 * {@link StructuralPropertyDescriptor})
183 */
184 public static List propertyDescriptors(int apiLevel)
185 {
186 if(apiLevel == AST.JLS3)
187 return PROPERTY_DESCRIPTORS_3_0;
188 else
189 return PROPERTY_DESCRIPTORS_2_0;
190 }
191
192 final SimplePropertyDescriptor internalModifiersProperty()
193 {
194 return MODIFIERS_PROPERTY;
195 }
196
197 final ChildListPropertyDescriptor internalModifiers2Property()
198 {
199 return MODIFIERS2_PROPERTY;
200 }
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000201
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000202 final ChildListPropertyDescriptor internalParameterMappingsProperty()
203 {
204 return PARAMETER_MAPPINGS_PROPERTY;
205 }
206
207 ChildPropertyDescriptor internalJavadocProperty()
208 {
209 return JAVADOC_PROPERTY;
210 }
211
Stephan Herrmann9ce31ef2010-05-24 20:13:45 +0000212 public ChildPropertyDescriptor getRoleElementProperty() {
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000213 return ROLE_MAPPING_ELEMENT_PROPERTY;
214 }
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000215
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000216 ChildPropertyDescriptor internalGetBindingOperatorProperty() {
217 return BINDING_OPERATOR_PROPERTY;
218 }
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000219
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000220 final int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean isGetRequest, int value)
221 {
222 if (property == MODIFIERS_PROPERTY)
223 {
224 if (isGetRequest)
225 {
226 return getModifiers();
227 }
228 else
229 {
230 setModifiers(value);
231 return 0;
232 }
233 }
234 // allow default implementation to flag the error
235 return super.internalGetSetIntProperty(property, isGetRequest, value);
236 }
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000237
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000238 final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean isGet, ASTNode child)
239 {
240 if (property == JAVADOC_PROPERTY)
241 {
242 if (isGet)
243 {
244 return getJavadoc();
245 }
246 else
247 {
248 setJavadoc((Javadoc) child);
249 return null;
250 }
251 }
252
253 if (property == BASE_MAPPING_ELEMENT_PROPERTY)
254 {
255 if (isGet)
256 {
257 return getBaseMappingElement();
258 }
259 else
260 {
261 setBaseMappingElement((MethodSpec) child);
262 return null;
263 }
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000264 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000265 // allow default implementation to flag the error (incl. handling of elements common to all method mappings):
266 return super.internalGetSetChildProperty(property, isGet, child);
267 }
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000268
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000269 final boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value)
270 {
271 if (property == SIGNATURE_PROPERTY)
272 {
273 if (get)
274 {
275 return hasSignature();
276 }
277 else
278 {
279 setSignatureFlag(value);
280 return false;
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000281 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000282 }
283 return super.internalGetSetBooleanProperty(property, get, value);
284 }
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000285
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000286 final List internalGetChildListProperty(ChildListPropertyDescriptor property)
287 {
288 if (property == PARAMETER_MAPPINGS_PROPERTY)
289 {
290 return getParameterMappings();
291 }
292 if (property == MODIFIERS2_PROPERTY)
293 {
294 return modifiers();
295 }
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000296
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000297 // allow default implementation to flag the error
298 return super.internalGetChildListProperty(property);
299 }
300
301 List internalStructuralPropertiesForType(int apiLevel)
302 {
303 return propertyDescriptors(apiLevel);
304 }
305
306 int getNodeType0()
307 {
308 return CALLOUT_MAPPING_DECLARATION;
309 }
310
311 @SuppressWarnings("unchecked")
312 ASTNode clone0(AST target)
313 {
314 CalloutMappingDeclaration result = new CalloutMappingDeclaration(target);
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000315 if (this.ast.apiLevel >= AST.JLS3)
316 result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers())); // annotations
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000317 result.setSourceRange(this.getStartPosition(), this.getLength());
318 result.setJavadoc(
319 (Javadoc) ASTNode.copySubtree(target, getJavadoc()));
320 result.setRoleMappingElement(
321 (MethodMappingElement) ASTNode.copySubtree(target, getRoleMappingElement()));
322 result.setBindingOperator((MethodBindingOperator)bindingOperator().clone(target));
323 result.setBaseMappingElement(
324 (MethodMappingElement) ASTNode.copySubtree(target, getBaseMappingElement()));
325 result.setSignatureFlag(this.hasSignature());
326 result.getParameterMappings().addAll(
327 ASTNode.copySubtrees(target, this.getParameterMappings()));
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000328
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000329 return result;
330 }
331
332 boolean subtreeMatch0(ASTMatcher matcher, Object other)
333 {
334 // dispatch to correct overloaded match method
335 return matcher.match(this, other);
336 }
337
338 void accept0(ASTVisitor visitor)
339 {
340 boolean visitChildren = visitor.visit(this);
341 if (visitChildren)
342 {
343 // visit children in normal left to right reading order
344 acceptChild(visitor, getJavadoc());
345 if (this.ast.apiLevel >= AST.JLS3)
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000346 acceptChildren(visitor, modifiers);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000347 acceptChild(visitor, roleMappingElement);
348 acceptChild(visitor, bindingOperator);
349 acceptChild(visitor, _baseMappingElement);
350 acceptChildren(visitor,_parameterMappings);
351 }
352 visitor.endVisit(this);
353 }
354
355 int treeSize()
356 {
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000357 return memSize() + (super.optionalDocComment == null
358 ? 0
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000359 : getJavadoc().treeSize());
360 }
361
362 /**
363 * Returns the method spec right of the callout arrow.
364 * @return the right method spec, i.e. the referenced base method
365 * @see Modifier
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000366 */
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000367 public MethodMappingElement getBaseMappingElement()
368 {
369 if (_baseMappingElement == null && !this._baseMappingInitialized)
370 {
371 // lazy init must be thread-safe for readers
372 synchronized (this)
373 {
374 if (_baseMappingElement == null)
375 {
376 preLazyInit();
377 _baseMappingElement = new MethodSpec(this.ast);
378 this._baseMappingInitialized= true;
379 postLazyInit(_baseMappingElement, BASE_MAPPING_ELEMENT_PROPERTY);
380 }
381 }
382 }
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000383 return _baseMappingElement;
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000384 }
385
386 /**
387 * Sets the right method spec (base method spec) declared in this callout
388 * mapping declaration to the given method spec.
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000389 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000390 * @param baseMappingElement
391 * @exception IllegalArgumentException if:
392 * <ul>
393 * <li>the node belongs to a different AST</li>
394 * <li>the node already has a parent</li>
395 * </ul>
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000396 */
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000397 public void setBaseMappingElement(MethodMappingElement baseMappingElement)
398 {
399 this._baseMappingInitialized= true;
400 ASTNode oldChild = _baseMappingElement;
401 preReplaceChild(oldChild, baseMappingElement, BASE_MAPPING_ELEMENT_PROPERTY);
402 _baseMappingElement = baseMappingElement;
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000403 postReplaceChild(oldChild, baseMappingElement, BASE_MAPPING_ELEMENT_PROPERTY);
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000404 }
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000405
Stephan Herrmann3421d292010-05-24 12:15:47 +0000406 /**
407 * {@inheritDoc}
408 */
409 @Override
410 public void removeSignatures() {
411 super.removeSignatures();
412 removeSignatureFrom(getBaseMappingElement());
413 }
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000414
415 /**
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000416 *
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000417 * @return the flag, whether callout is a callout override or a simple callout
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000418 * true, if an override;
419 */
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000420 public boolean isCalloutOverride()
421 {
422 return this.bindingOperator().getBindingKind() == MethodBindingOperator.KIND_CALLOUT_OVERRIDE;
423 }
424
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000425 public boolean hasSignature()
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000426 {
427 return _hasSignature;
428 }
429
Stephan Herrmannab1b9762010-09-26 14:31:00 +0000430 public void setSignatureFlag(boolean hasSignature)
Stephan Herrmann7b7062f2010-04-01 19:56:59 +0000431 {
432 preValueChange(SIGNATURE_PROPERTY);
433 _hasSignature = hasSignature;
434 postValueChange(SIGNATURE_PROPERTY);
435 }
436}