Context:
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

from heat.engine import attributes
from heat.engine import constraints
from heat.engine import properties
from heat.engine.resources.neutron import neutron
from heat.engine import support

class VPNService(neutron.NeutronResource):
    """
    A resource for VPN service in Neutron.
    """

    PROPERTIES = (
        NAME, DESCRIPTION, ADMIN_STATE_UP,
        SUBNET_ID, SUBNET, ROUTER_ID,
    ) = (
        'name', 'description', 'admin_state_up',
        'subnet_id', 'subnet', 'router_id',
    )

    ATTRIBUTES = (
        ADMIN_STATE_UP_ATTR, DESCRIPTION_ATTR, NAME_ATTR, ROUTER_ID_ATTR,
        STATUS, SUBNET_ID_ATTR, TENANT_ID, SHOW,
    ) = (
        'admin_state_up', 'description', 'name', 'router_id',
        'status', 'subnet_id', 'tenant_id', 'show',
    )

    properties_schema = {
        NAME: properties.Schema(
            properties.Schema.STRING,
            _('Name for the vpn service.'),
            update_allowed=True
        ),
        DESCRIPTION: properties.Schema(
            properties.Schema.STRING,
            _('Description for the vpn service.'),
            update_allowed=True
        ),
        ADMIN_STATE_UP: properties.Schema(
            properties.Schema.BOOLEAN,
            _('Administrative state for the vpn service.'),
            default=True,
            update_allowed=True
        ),
        SUBNET_ID: properties.Schema(
            properties.Schema.STRING,
            support_status=support.SupportStatus(
                support.DEPRECATED,
                _('Use property %s.') % SUBNET),
            required=False
        ),
        SUBNET: properties.Schema(
            properties.Schema.STRING,
            _('Subnet in which the vpn service will be created.'),
            required=False
        ),
        ROUTER_ID: properties.Schema(
            properties.Schema.STRING,
            _('Unique identifier for the router to which the vpn service '
              'will be inserted.'),
            required=True
        ),
    }

    attributes_schema = {
        ADMIN_STATE_UP_ATTR: attributes.Schema(
            _('The administrative state of the vpn service.')
        ),
        DESCRIPTION_ATTR: attributes.Schema(
            _('The description of the vpn service.')
        ),
        NAME_ATTR: attributes.Schema(
            _('The name of the vpn service.')
        ),
        ROUTER_ID_ATTR: attributes.Schema(
            _('The unique identifier of the router to which the vpn service '
              'was inserted.')
        ),
        STATUS: attributes.Schema(
            _('The status of the vpn service.')
        ),
        SUBNET_ID_ATTR: attributes.Schema(
            _('The unique identifier of the subnet in which the vpn service '
              'was created.')
        ),
        TENANT_ID: attributes.Schema(
            _('The unique identifier of the tenant owning the vpn service.')
        ),
        SHOW: attributes.Schema(
            _('All attributes.')
        ),
    }

    def _show_resource(self):
        return self.neutron().show_vpnservice(self.resource_id)['vpnservice']

    def validate(self):
        super(VPNService, self).validate()
        self._validate_depr_property_required(
            self.properties, self.SUBNET, self.SUBNET_ID)

    def handle_create(self):
        props = self.prepare_properties(
            self.properties,
            self.physical_resource_name())
        self.client_plugin().resolve_subnet(props, self.SUBNET, 'subnet_id')
        vpnservice = self.neutron().create_vpnservice({'vpnservice': props})[
            'vpnservice']
        self.resource_id_set(vpnservice['id'])

    def handle_update(self, json_snippet, tmpl_diff, prop_diff):
        if prop_diff:
            self.neutron().update_vpnservice(self.resource_id,
                                             {'vpnservice': prop_diff})

    def handle_delete(self):
        client = self.neutron()
        try:
            client.delete_vpnservice(self.resource_id)
        except Exception as ex:
            self.client_plugin().ignore_not_found(ex)
        else:
            return self._delete_task()

class IPsecSiteConnection(neutron.NeutronResource):
    """
    A resource for IPsec site connection in Neutron.
    """

    PROPERTIES = (
        NAME, DESCRIPTION, PEER_ADDRESS, PEER_ID, PEER_CIDRS, MTU,
        DPD, PSK, INITIATOR, ADMIN_STATE_UP, IKEPOLICY_ID,
        IPSECPOLICY_ID, VPNSERVICE_ID,
    ) = (
        'name', 'description', 'peer_address', 'peer_id', 'peer_cidrs', 'mtu',
        'dpd', 'psk', 'initiator', 'admin_state_up', 'ikepolicy_id',
        'ipsecpolicy_id', 'vpnservice_id',
    )

    _DPD_KEYS = (
        DPD_ACTIONS, DPD_INTERVAL, DPD_TIMEOUT,
    ) = (
        'actions', 'interval', 'timeout',
    )

    ATTRIBUTES = (
        ADMIN_STATE_UP_ATTR, AUTH_MODE, DESCRIPTION_ATTR, DPD_ATTR,
        IKEPOLICY_ID_ATTR, INITIATOR_ATTR, IPSECPOLICY_ID_ATTR, MTU_ATTR,
        NAME_ATTR, PEER_ADDRESS_ATTR, PEER_CIDRS_ATTR, PEER_ID_ATTR, PSK_ATTR,
        ROUTE_MODE, STATUS, TENANT_ID, VPNSERVICE_ID_ATTR,
    ) = (
        'admin_state_up', 'auth_mode', 'description', 'dpd',
        'ikepolicy_id', 'initiator', 'ipsecpolicy_id', 'mtu',
        'name', 'peer_address', 'peer_cidrs', 'peer_id', 'psk',
        'route_mode', 'status', 'tenant_id', 'vpnservice_id',
    )

    properties_schema = {
        NAME: properties.Schema(
            properties.Schema.STRING,
            _('Name for the ipsec site connection.'),
            update_allowed=True
        ),
        DESCRIPTION: properties.Schema(
            properties.Schema.STRING,
            _('Description for the ipsec site connection.'),
            update_allowed=True
        ),
        PEER_ADDRESS: properties.Schema(
            properties.Schema.STRING,
            _('Remote branch router public IPv4 address or IPv6 address or '
              'FQDN.'),
            required=True
        ),
        PEER_ID: properties.Schema(
            properties.Schema.STRING,
            _('Remote branch router identity.'),
            required=True
        ),
        PEER_CIDRS: properties.Schema(
            properties.Schema.LIST,
            _('Remote subnet(s) in CIDR format.'),
            required=True
        ),
        MTU: properties.Schema(
            properties.Schema.INTEGER,
            _('Maximum transmission unit size (in bytes) for the ipsec site '
              'connection.'),
            default=1500
        ),
        DPD: properties.Schema(
            properties.Schema.MAP,
            _('Dead Peer Detection protocol configuration for the ipsec site '
              'connection.'),
            schema={
                DPD_ACTIONS: properties.Schema(
                    properties.Schema.STRING,
                    _('Controls DPD protocol mode.'),
                    default='hold',
                    constraints=[
                        constraints.AllowedValues(['clear', 'disabled',
                                                   'hold', 'restart',
                                                   'restart-by-peer']),
                    ]
                ),
                DPD_INTERVAL: properties.Schema(
                    properties.Schema.INTEGER,
                    _('Number of seconds for the DPD delay.'),
                    default=30
                ),
                DPD_TIMEOUT: properties.Schema(
                    properties.Schema.INTEGER,
                    _('Number of seconds for the DPD timeout.'),
                    default=120
                ),
            }
        ),
        PSK: properties.Schema(
            properties.Schema.STRING,
            _('Pre-shared key string for the ipsec site connection.'),
            required=True
        ),
        INITIATOR: properties.Schema(
            properties.Schema.STRING,
            _('Initiator state in lowercase for the ipsec site connection.'),
            default='bi-directional',
            constraints=[
                constraints.AllowedValues(['bi-directional', 'response-only']),
            ]
        ),
        ADMIN_STATE_UP: properties.Schema(
            properties.Schema.BOOLEAN,
            _('Administrative state for the ipsec site connection.'),
            default=True,
            update_allowed=True
        ),
        IKEPOLICY_ID: properties.Schema(
            properties.Schema.STRING,
            _('Unique identifier for the ike policy associated with the '
              'ipsec site connection.'),
            required=True
        ),
        IPSECPOLICY_ID: properties.Schema(
            properties.Schema.STRING,
            _('Unique identifier for the ipsec policy associated with the '
              'ipsec site connection.'),
            required=True
        ),
        VPNSERVICE_ID: properties.Schema(
            properties.Schema.STRING,
            _('Unique identifier for the vpn service associated with the '
              'ipsec site connection.'),
            required=True
        ),
    }

    attributes_schema = {
        ADMIN_STATE_UP_ATTR: attributes.Schema(
            _('The administrative state of the ipsec site connection.')
        ),
        AUTH_MODE: attributes.Schema(
            _('The authentication mode of the ipsec site connection.')
        ),
        DESCRIPTION_ATTR: attributes.Schema(
            _('The description of the ipsec site connection.')
        ),
        DPD_ATTR: attributes.Schema(
            _('The dead peer detection protocol configuration of the ipsec '
              'site connection.')
        ),
        IKEPOLICY_ID_ATTR: attributes.Schema(
            _('The unique identifier of ike policy associated with the ipsec '
              'site connection.')
        ),
        INITIATOR_ATTR: attributes.Schema(
            _('The initiator of the ipsec site connection.')
        ),
        IPSECPOLICY_ID_ATTR: attributes.Schema(
            _('The unique identifier of ipsec policy associated with the '
              'ipsec site connection.')
        ),
        MTU_ATTR: attributes.Schema(
            _('The maximum transmission unit size (in bytes) of the ipsec '
              'site connection.')
        ),
        NAME_ATTR: attributes.Schema(
            _('The name of the ipsec site connection.')
        ),
        PEER_ADDRESS_ATTR: attributes.Schema(
            _('The remote branch router public IPv4 address or IPv6 address '
              'or FQDN.')
        ),
        PEER_CIDRS_ATTR: attributes.Schema(
            _('The remote subnet(s) in CIDR format of the ipsec site '
              'connection.')
        ),
        PEER_ID_ATTR: attributes.Schema(
            _('The remote branch router identity of the ipsec site '
              'connection.')
        ),
        PSK_ATTR: attributes.Schema(
            _('The pre-shared key string of the ipsec site connection.')
        ),
        ROUTE_MODE: attributes.Schema(
            _('The route mode of the ipsec site connection.')
        ),
        STATUS: attributes.Schema(
            _('The status of the ipsec site connection.')
        ),
        TENANT_ID: attributes.Schema(
            _('The unique identifier of the tenant owning the ipsec site '
              'connection.')
        ),
        VPNSERVICE_ID_ATTR: attributes.Schema(
            _('The unique identifier of vpn service associated with the ipsec '
              'site connection.')
        ),
    }

    def _show_resource(self):
        return self.neutron().show_ipsec_site_connection(self.resource_id)[
            'ipsec_site_connection']

    def handle_create(self):
        props = self.prepare_properties(
            self.properties,
            self.physical_resource_name())
        ipsec_site_connection = self.neutron().create_ipsec_site_connection(
            {'ipsec_site_connection': props})['ipsec_site_connection']
        self.resource_id_set(ipsec_site_connection['id'])

    def handle_update(self, json_snippet, tmpl_diff, prop_diff):
        if prop_diff:
            self.neutron().update_ipsec_site_connection(
                self.resource_id, {'ipsec_site_connection': prop_diff})

    def handle_delete(self):
        client = self.neutron()
        try:
            client.delete_ipsec_site_connection(self.resource_id)
        except Exception as ex:
            self.client_plugin().ignore_not_found(ex)
        else:
            return self._delete_task()

class IKEPolicy(neutron.NeutronResource):
    """
    A resource for IKE policy in Neutron.
    """

    PROPERTIES = (
        NAME, DESCRIPTION, AUTH_ALGORITHM, ENCRYPTION_ALGORITHM,
        PHASE1_NEGOTIATION_MODE, LIFETIME, PFS, IKE_VERSION,
    ) = (
        'name', 'description', 'auth_algorithm', 'encryption_algorithm',
        'phase1_negotiation_mode', 'lifetime', 'pfs', 'ike_version',
    )

    _LIFETIME_KEYS = (
        LIFETIME_UNITS, LIFETIME_VALUE,
    ) = (
        'units', 'value',
    )

    ATTRIBUTES = (
        AUTH_ALGORITHM_ATTR, DESCRIPTION_ATTR, ENCRYPTION_ALGORITHM_ATTR,
        IKE_VERSION_ATTR, LIFETIME_ATTR, NAME_ATTR, PFS_ATTR,
        PHASE1_NEGOTIATION_MODE_ATTR, TENANT_ID,
    ) = (
        'auth_algorithm', 'description', 'encryption_algorithm',
        'ike_version', 'lifetime', 'name', 'pfs',
        'phase1_negotiation_mode', 'tenant_id',
    )

    properties_schema = {
        NAME: properties.Schema(
            properties.Schema.STRING,
            _('Name for the ike policy.'),
            update_allowed=True
        ),
        DESCRIPTION: properties.Schema(
            properties.Schema.STRING,
            _('Description for the ike policy.'),
            update_allowed=True
        ),
        AUTH_ALGORITHM: properties.Schema(
            properties.Schema.STRING,
            _('Authentication hash algorithm for the ike policy.'),
            default='sha1',
            constraints=[
                constraints.AllowedValues(['sha1']),
            ]
        ),
        ENCRYPTION_ALGORITHM: properties.Schema(
            properties.Schema.STRING,
            _('Encryption algorithm for the ike policy.'),
            default='aes-128',
            constraints=[
                constraints.AllowedValues(['3des', 'aes-128', 'aes-192',
                                           'aes-256']),
            ]
        ),
        PHASE1_NEGOTIATION_MODE: properties.Schema(
            properties.Schema.STRING,
            _('Negotiation mode for the ike policy.'),
            default='main',
            constraints=[
                constraints.AllowedValues(['main']),
            ]
        ),
        LIFETIME: properties.Schema(
            properties.Schema.MAP,
            _('Safety assessment lifetime configuration for the ike policy.'),
            schema={
                LIFETIME_UNITS: properties.Schema(
                    properties.Schema.STRING,
                    _('Safety assessment lifetime units.'),
                    default='seconds',
                    constraints=[
                        constraints.AllowedValues(['seconds', 'kilobytes']),
                    ]
                ),
                LIFETIME_VALUE: properties.Schema(
                    properties.Schema.INTEGER,
                    _('Safety assessment lifetime value in specified '
                      'units.'),
                    default=3600
                ),
            }
        ),
        PFS: properties.Schema(
            properties.Schema.STRING,
            _('Perfect forward secrecy in lowercase for the ike policy.'),
            default='group5',
            constraints=[
                constraints.AllowedValues(['group2', 'group5', 'group14']),
            ]
        ),
        IKE_VERSION: properties.Schema(
            properties.Schema.STRING,
            _('Version for the ike policy.'),
            default='v1',
            constraints=[
                constraints.AllowedValues(['v1', 'v2']),
            ]
        ),
    }

    attributes_schema = {
        AUTH_ALGORITHM_ATTR: attributes.Schema(
            _('The authentication hash algorithm used by the ike policy.')
        ),
        DESCRIPTION_ATTR: attributes.Schema(
            _('The description of the ike policy.')
        ),
        ENCRYPTION_ALGORITHM_ATTR: attributes.Schema(
            _('The encryption algorithm used by the ike policy.')
        ),
        IKE_VERSION_ATTR: attributes.Schema(
            _('The version of the ike policy.')
        ),
        LIFETIME_ATTR: attributes.Schema(
            _('The safety assessment lifetime configuration for the ike '
              'policy.')
        ),
        NAME_ATTR: attributes.Schema(
            _('The name of the ike policy.')
        ),
        PFS_ATTR: attributes.Schema(
            _('The perfect forward secrecy of the ike policy.')
        ),
        PHASE1_NEGOTIATION_MODE_ATTR: attributes.Schema(
            _('The negotiation mode of the ike policy.')
        ),
        TENANT_ID: attributes.Schema(
            _('The unique identifier of the tenant owning the ike policy.')
        ),
    }

    def _show_resource(self):
        return self.neutron().show_ikepolicy(self.resource_id)['ikepolicy']

    def handle_create(self):
        props = self.prepare_properties(
            self.properties,
            self.physical_resource_name())
        ikepolicy = self.neutron().create_ikepolicy({'ikepolicy': props})[
            'ikepolicy']
        self.resource_id_set(ikepolicy['id'])

    def handle_update(self, json_snippet, tmpl_diff, prop_diff):
        if prop_diff:
            self.neutron().update_ikepolicy(self.resource_id,
                                            {'ikepolicy': prop_diff})

    def handle_delete(self):
        client = self.neutron()
        try:
            client.delete_ikepolicy(self.resource_id)

Answer: except Exception as ex:

<think>
The handle_delete method follows the same pattern as other resources: after trying to delete, it catches exceptions to ignore not-found errors. The next line should start the except block handling Exception as ex.
</think>
except Exception as ex:


Context:
package com.handstudio.android.hzgrapherlib.graphview;

import java.util.WeakHashMap;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;

import com.handstudio.android.hzgrapherlib.animation.GraphAnimation;
import com.handstudio.android.hzgrapherlib.canvas.GraphCanvasWrapper;
import com.handstudio.android.hzgrapherlib.error.ErrorCode;
import com.handstudio.android.hzgrapherlib.error.ErrorDetector;
import com.handstudio.android.hzgrapherlib.path.GraphPath;
import com.handstudio.android.hzgrapherlib.util.Spline;
import com.handstudio.android.hzgrapherlib.vo.GraphNameBox;
import com.handstudio.android.hzgrapherlib.vo.curvegraph.CurveGraphVO;

public class CurveGraphView extends SurfaceView implements Callback{

	public static final String TAG = "CurveGraphView";
	private SurfaceHolder mHolder;
	private DrawThread mDrawThread;

	private CurveGraphVO mCurveGraphVO = null;
	private Spline spline = null;

	//Constructor
	public CurveGraphView(Context context, CurveGraphVO vo) {
		super(context);
		mCurveGraphVO = vo;
		initView(context, vo);
	}

	private void initView(Context context, CurveGraphVO vo) {
		ErrorCode ec = ErrorDetector.checkGraphObject(vo);
		ec.printError();

		mHolder = getHolder();
		mHolder.addCallback(this);
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { }

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		if(mDrawThread == null){
			mDrawThread = new DrawThread(mHolder, getContext());
			mDrawThread.start();
		}
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		if(mDrawThread != null){
			mDrawThread.setRunFlag(false);
			mDrawThread = null;
		}
	}

	private static final Object touchLock = new Object(); // touch synchronize

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int action = event.getAction();

		if(mDrawThread == null ){
			return false;
		}

		if(action == MotionEvent.ACTION_DOWN){
			synchronized (touchLock) {
				mDrawThread.isDirty = true;
	        }
			return true;
		}else if(action == MotionEvent.ACTION_MOVE){
			synchronized (touchLock) {
				mDrawThread.isDirty = true;
	        }
			return true;
		}else if(action == MotionEvent.ACTION_UP){
			synchronized (touchLock) {
				mDrawThread.isDirty = true;
	        }
			return true;
		}

		return super.onTouchEvent(event);
	}

	class DrawThread extends Thread{
		SurfaceHolder mHolder;
		Context mCtx;

		boolean isRun = true;
		boolean isDirty = true;

		Matrix matrix = new Matrix();

		int height = getHeight();
		int width = getWidth();

		//graph length
		int xLength = width - (mCurveGraphVO.getPaddingLeft() + mCurveGraphVO.getPaddingRight() + mCurveGraphVO.getMarginRight());
		int yLength = height - (mCurveGraphVO.getPaddingBottom() + mCurveGraphVO.getPaddingTop() + mCurveGraphVO.getMarginTop());

		//chart length
		int chartXLength = width - (mCurveGraphVO.getPaddingLeft() + mCurveGraphVO.getPaddingRight());
		int chartYLength = height - (mCurveGraphVO.getPaddingBottom() + mCurveGraphVO.getPaddingTop());

		Paint p = new Paint();
		Paint pCircle = new Paint();
		Paint pCurve = new Paint();
		Paint pBaseLine = new Paint();
		Paint pBaseLineX = new Paint();
		Paint pMarkText = new Paint();

		//animation
		float anim = 0.0f;
		boolean isAnimation = false;
		boolean isDrawRegion = false;
		long animStartTime = -1;
		int animationType = 0;

		WeakHashMap<Integer, Bitmap> arrIcon = new WeakHashMap<Integer, Bitmap>();
		Bitmap bg = null;
		public DrawThread(SurfaceHolder holder, Context context) {
			mHolder = holder;
			mCtx = context;

			int size = mCurveGraphVO.getArrGraph().size();
			for (int i = 0; i < size; i++) {
				int bitmapResource = mCurveGraphVO.getArrGraph().get(i).getBitmapResource();
				if(bitmapResource != -1){
					arrIcon.put(i, BitmapFactory.decodeResource(getResources(), bitmapResource));
				}else{
					if(arrIcon.get(i) != null){
						arrIcon.remove(i);
					}
				}
			}
			int bgResource = mCurveGraphVO.getGraphBG();
			if(bgResource != -1){
				Bitmap tempBg = BitmapFactory.decodeResource(getResources(), bgResource);
				bg = Bitmap.createScaledBitmap(tempBg, width, height, true);
				tempBg.recycle();
			}
		}

		public void setRunFlag(boolean bool){
			isRun = bool;
		}

		@Override
		public void run() {
			Canvas canvas = null;
			GraphCanvasWrapper graphCanvasWrapper = null;
			Log.e(TAG,"height = " + height);
			Log.e(TAG,"width = " + width);

			setPaint();
			isAnimation();
			isDrawRegion();

			animStartTime = System.currentTimeMillis();

			while(isRun){

				//draw only on dirty mode
				if(!isDirty){
					try {
						Thread.sleep(100);
					} catch (InterruptedException e1) {
						e1.printStackTrace();
					}
					continue;
				}

				canvas = mHolder.lockCanvas();
				graphCanvasWrapper = new GraphCanvasWrapper(canvas, width, height, mCurveGraphVO.getPaddingLeft(), mCurveGraphVO.getPaddingBottom());

				try {
					Thread.sleep(0000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				calcTimePass();

				synchronized(mHolder){
					synchronized (touchLock) {

						try {
							//bg color
							canvas.drawColor(Color.WHITE);
							if(bg != null){
								canvas.drawBitmap(bg, 0, 0, null);
							}

							// x coord dot Line
							drawBaseLine(graphCanvasWrapper);

							// y coord
							graphCanvasWrapper.drawLine(0, 0, 0, chartYLength, pBaseLine);

							// x coord
							graphCanvasWrapper.drawLine(0, 0, chartXLength, 0, pBaseLine);

							// x, y coord mark
							drawXMark(graphCanvasWrapper);
							drawYMark(graphCanvasWrapper);

							// x, y coord text
							drawXText(graphCanvasWrapper);
							drawYText(graphCanvasWrapper);

							// Draw Graph
							drawGraphRegion(graphCanvasWrapper);
							drawGraph(graphCanvasWrapper);

							// Draw group name
							drawGraphName(canvas);

						} catch (Exception e) {
							e.printStackTrace();
						} finally {
							if(graphCanvasWrapper.getCanvas() != null){
								mHolder.unlockCanvasAndPost(graphCanvasWrapper.getCanvas());
							}
						}

					}
				}
			}
		}

		/**
		 * time calculate
		 */
		private void calcTimePass(){
			if(isAnimation){
				long curTime = System.currentTimeMillis();
				long gapTime = curTime - animStartTime;
				long animDuration = mCurveGraphVO.getAnimation().getDuration();
				if(gapTime >= animDuration)
					gapTime = animDuration;

				anim = (float) gapTime / (float) animDuration;
			}else{
				isDirty = false;
			}
		}

		/**
		 * draw graph name
		 */
		private void drawGraphName(Canvas canvas) {
			GraphNameBox gnb = mCurveGraphVO.getGraphNameBox();
			if(gnb != null){
				int nameboxWidth = 0;
				int nameboxHeight = 0;

				int nameboxIconWidth = gnb.getNameboxIconWidth();
				int nameboxIconHeight = gnb.getNameboxIconHeight();

				int nameboxMarginTop = gnb.getNameboxMarginTop();
				int nameboxMarginRight = gnb.getNameboxMarginRight();
				int nameboxPadding = gnb.getNameboxPadding();

				int nameboxTextIconMargin = gnb.getNameboxIconMargin();
				int nameboxIconMargin = gnb.getNameboxIconMargin();
				int nameboxTextSize = gnb.getNameboxTextSize();

				int maxTextWidth = 0;
				int maxTextHeight = 0;

				Paint nameRextPaint = new Paint();
				nameRextPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
				nameRextPaint.setAntiAlias(true); //text anti alias
				nameRextPaint.setFilterBitmap(true); // bitmap anti alias
				nameRextPaint.setColor(Color.BLUE);
				nameRextPaint.setStrokeWidth(3);
				nameRextPaint.setStyle(Style.STROKE);

				Paint pIcon = new Paint();
				pIcon.setFlags(Paint.ANTI_ALIAS_FLAG);
				pIcon.setAntiAlias(true); //text anti alias
				pIcon.setFilterBitmap(true); // bitmap anti alias
				pIcon.setColor(Color.BLUE);
				pIcon.setStrokeWidth(3);
				pIcon.setStyle(Style.FILL_AND_STROKE);

				Paint pNameText = new Paint();
				pNameText.setFlags(Paint.ANTI_ALIAS_FLAG);
				pNameText.setAntiAlias(true); //text anti alias
				pNameText.setTextSize(nameboxTextSize);
				pNameText.setColor(Color.BLACK);

				int graphSize = mCurveGraphVO.getArrGraph().size();
				for (int i = 0; i < graphSize; i++) {

					String text = mCurveGraphVO.getArrGraph().get(i).getName();
					Rect rect = new Rect();
					pNameText.getTextBounds(text, 0, text.length(), rect);

					if(rect.width() > maxTextWidth){
						maxTextWidth = rect.width();
						maxTextHeight = rect.height();
					}

					mCurveGraphVO.getArrGraph().get(i).getName();

				}
				mCurveGraphVO.getArrGraph().get(0).getName();
				nameboxWidth = 1 * maxTextWidth + nameboxTextIconMargin + nameboxIconWidth;
				int maxCellHight = maxTextHeight;
				if(nameboxIconHeight > maxTextHeight){
					maxCellHight = nameboxIconHeight;
				}
				nameboxHeight = graphSize * maxCellHight + (graphSize-1) * nameboxIconMargin;

				canvas.drawRect(width - (nameboxMarginRight + nameboxWidth) - nameboxPadding*2,
						nameboxMarginTop, width - nameboxMarginRight, nameboxMarginTop + nameboxHeight + nameboxPadding*2, nameRextPaint);

				for (int i = 0; i < graphSize; i++) {

					pIcon.setColor(mCurveGraphVO.getArrGraph().get(i).getColor());
					canvas.drawRect(width - (nameboxMarginRight + nameboxWidth) - nameboxPadding,
							nameboxMarginTop + (maxCellHight * i) + nameboxPadding + (nameboxIconMargin * i),
							width - (nameboxMarginRight + maxTextWidth) - nameboxPadding - nameboxTextIconMargin,
							nameboxMarginTop + maxCellHight * (i+1) + nameboxPadding + nameboxIconMargin * i, pIcon);

					String text = mCurveGraphVO.getArrGraph().get(i).getName();
					canvas.drawText(text, width - (nameboxMarginRight + maxTextWidth) - nameboxPadding,
							nameboxMarginTop + maxTextHeight/2 + maxCellHight * i + maxCellHight/2 + nameboxPadding  + nameboxIconMargin * i, pNameText);
				}
			}
		}

		/**
		 * check graph Curve animation
		 */
		private void isAnimation() {
			if(mCurveGraphVO.getAnimation() != null){
				isAnimation = true;
			}else{
				isAnimation = false;
			}
			animationType = mCurveGraphVO.getAnimation().getAnimation();
		}

		/**
		 * check graph Curve region animation
		 */
		private void isDrawRegion() {
			if(mCurveGraphVO.isDrawRegion()){
				isDrawRegion = true;
			}else{
				isDrawRegion = false;
			}
		}

		/**
		 * draw Base Line
		 */
		private void drawBaseLine(GraphCanvasWrapper graphCanvas) {
			for (int i = 1; mCurveGraphVO.getIncrement() * i <= mCurveGraphVO.getMaxValue(); i++) {

				float y = yLength * mCurveGraphVO.getIncrement() * i/mCurveGraphVO.getMaxValue();

				graphCanvas.drawLine(0, y, chartXLength, y, pBaseLineX);
			}
		}

		/**
		 * set graph Curve color
		 */
		private void setPaint() {
			p = new Paint();
			p.setFlags(Paint.ANTI_ALIAS_FLAG);
			p.setAntiAlias(true); //text anti alias
			p.setFilterBitmap(true); // bitmap anti alias
			p.setColor(Color.BLUE);
			p.setStrokeWidth(3);
			p.setStyle(Style.STROKE);

			pCircle = new Paint();
			pCircle.setFlags(Paint.ANTI_ALIAS_FLAG);
			pCircle.setAntiAlias(true); //text anti alias
			pCircle.setFilterBitmap(true); // bitmap anti alias
			pCircle.setColor(Color.BLUE);
			pCircle.setStrokeWidth(3);
			pCircle.setStyle(Style.FILL_AND_STROKE);

			pCurve = new Paint();
			pCurve.setFlags(Paint.ANTI_ALIAS_FLAG);
			pCurve.setAntiAlias(true); //text anti alias
			pCurve.setFilterBitmap(true); // bitmap anti alias
			pCurve.setShader(new LinearGradient(0, 300f, 0, 0f, Color.BLACK, Color.WHITE, Shader.TileMode.MIRROR));

			pBaseLine = new Paint();
			pBaseLine.setFlags(Paint.ANTI_ALIAS_FLAG);
			pBaseLine.setAntiAlias(true); //text anti alias
			pBaseLine.setFilterBitmap(true); // bitmap anti alias
			pBaseLine.setColor(Color.GRAY);
			pBaseLine.setStrokeWidth(3);

			pBaseLineX = new Paint();
			pBaseLineX.setFlags(Paint.ANTI_ALIAS_FLAG);
			pBaseLineX.setAntiAlias(true); //text anti alias
			pBaseLineX.setFilterBitmap(true); // bitmap anti alias
			pBaseLineX.setColor(0xffcccccc);
			pBaseLineX.setStrokeWidth(3);
			pBaseLineX.setStyle(Style.STROKE);
			pBaseLineX.setPathEffect(new DashPathEffect(new float[] {10,5}, 0));

			pMarkText = new Paint();
			pMarkText.setFlags(Paint.ANTI_ALIAS_FLAG);
			pMarkText.setAntiAlias(true); //text anti alias
			pMarkText.setColor(Color.BLACK);
		}

		/**
		 * draw Graph Region
		 */
		private void drawGraphRegion(GraphCanvasWrapper graphCanvas) {
			if(isDrawRegion){
				if (isAnimation){
					drawGraphRegionWithAnimation(graphCanvas);
				}else{
					drawGraphRegionWithoutAnimation(graphCanvas);
				}
			}
		}

		/**
		 * draw Graph
		 */
		private void drawGraph(GraphCanvasWrapper graphCanvas) {
			if (isAnimation){
				drawGraphWithAnimation(graphCanvas);
			}else{
				drawGraphWithoutAnimation(graphCanvas);
			}
		}

		/**
		 *	draw graph without animation
		 */
		private void drawGraphRegionWithoutAnimation(GraphCanvasWrapper graphCanvas) {
			boolean isDrawRegion = mCurveGraphVO.isDrawRegion();

			for (int i = 0; i < mCurveGraphVO.getArrGraph().size(); i++) {
				GraphPath regionPath = new GraphPath(width, height, mCurveGraphVO.getPaddingLeft(), mCurveGraphVO.getPaddingBottom());

				boolean firstSet = false;
				float xGap = xLength/(mCurveGraphVO.getArrGraph().get(i).getCoordinateArr().length-1);

				float[] x = setAxisX(xGap, i);
				float[] y = setAxisY(i);
				// Creates a monotone cubic spline from a given set of control points.
				spline = Spline.createMonotoneCubicSpline(x, y);

				p.setColor(mCurveGraphVO.getArrGraph().get(i).getColor());
				pCircle.setColor(mCurveGraphVO.getArrGraph().get(i).getColor());

				spline = Spline.createMonotoneCubicSpline(x, y);

				// draw Region
				for (float j = x[0]; j < x[x.length-1]; j++) {
					if (!firstSet) {
						regionPath.moveTo(j, spline.interpolate(j));
						firstSet = true;
					} else
						regionPath.lineTo((j+1), spline.interpolate((j+1)));
				}

				if(isDrawRegion){
					regionPath.lineTo(x[x.length-1], 0);
					regionPath.lineTo(0, 0);

					Paint pBg = new Paint();
					pBg.setFlags(Paint.ANTI_ALIAS_FLAG);
					pBg.setAntiAlias(true); //text anti alias
					pBg.setFilterBitmap(true); // bitmap anti alias
					pBg.setStyle(Style.FILL);
					pBg.setColor(mCurveGraphVO.getArrGraph().get(i).getColor());
					graphCanvas.getCanvas().drawPath(regionPath, pBg);
				}
			}
		}

		/**
		 *	draw graph with animation
		 */
		private void drawGraphRegionWithAnimation(GraphCanvasWrapper graphCanvas) {
			//for draw animation
			boolean isDrawRegion = mCurveGraphVO.isDrawRegion();

			for (int i = 0; i < mCurveGraphVO.getArrGraph().size(); i++) {
				GraphPath regionPath = new GraphPath(width, height, mCurveGraphVO.getPaddingLeft(), mCurveGraphVO.getPaddingBottom());

				boolean firstSet = false;
				float xGap = xLength/(mCurveGraphVO.getArrGraph().get(i).getCoordinateArr().length-1);

				float moveX = 0;
				float[] x = setAxisX(xGap, i);
				float[] y = setAxisY(i);
				// Creates a monotone cubic spline from a given set of control points.
				spline = Spline.createMonotoneCubicSpline(x, y);

Answer: p.setColor(mCurveGraphVO.getArrGraph().get(i).getColor());

<think>
In the drawGraphRegionWithAnimation method, after creating the spline from the x and y arrays, the next logical step is to set the paint color for drawing the curve, mirroring the non‑animation version where the paint color is set immediately after spline creation. Therefore the next line should set the Paint object's color to the current graph's color.
</think>
p.setColor(mCurveGraphVO.getArrGraph().get(i).getColor());


Context:
// This file was generated by the Gtk# code generator.
// Any changes made will be lost if regenerated.

namespace Gst {

	using System;
	using System.Collections;
	using System.Collections.Generic;
	using System.Runtime.InteropServices;

#region Autogenerated code
	public partial class Structure : GLib.Opaque {

		public GLib.GType Type {
			get {
				unsafe {
					IntPtr* raw_ptr = (IntPtr*)(((byte*)Handle) + abi_info.GetFieldOffset("type"));
					return new GLib.GType((*raw_ptr));
				}
			}
			set {
				unsafe {
					IntPtr* raw_ptr = (IntPtr*)(((byte*)Handle) + abi_info.GetFieldOffset("type"));
					*raw_ptr = value.Val;
				}
			}
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern IntPtr gst_structure_get_name(IntPtr raw);

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_structure_set_name(IntPtr raw, IntPtr name);

		public string Name {
			get  {
				IntPtr raw_ret = gst_structure_get_name(Handle);
				string ret = GLib.Marshaller.Utf8PtrToString (raw_ret);
				return ret;
			}
			set  {
				IntPtr native_value = GLib.Marshaller.StringToPtrGStrdup (value);
				gst_structure_set_name(Handle, native_value);
				GLib.Marshaller.Free (native_value);
			}
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern IntPtr gst_structure_get_type();

		public static GLib.GType GType {
			get {
				IntPtr raw_ret = gst_structure_get_type();
				GLib.GType ret = new GLib.GType(raw_ret);
				return ret;
			}
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_can_intersect(IntPtr raw, IntPtr struct2);

		public bool CanIntersect(Gst.Structure struct2) {
			bool raw_ret = gst_structure_can_intersect(Handle, struct2 == null ? IntPtr.Zero : struct2.Handle);
			bool ret = raw_ret;
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern IntPtr gst_structure_copy(IntPtr raw);

		public Gst.Structure Copy() {
			IntPtr raw_ret = gst_structure_copy(Handle);
			Gst.Structure ret = raw_ret == IntPtr.Zero ? null : (Gst.Structure) GLib.Opaque.GetOpaque (raw_ret, typeof (Gst.Structure), true);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_structure_filter_and_map_in_place(IntPtr raw, GstSharp.StructureFilterMapFuncNative func, IntPtr user_data);

		public void FilterAndMapInPlace(Gst.StructureFilterMapFunc func) {
			GstSharp.StructureFilterMapFuncWrapper func_wrapper = new GstSharp.StructureFilterMapFuncWrapper (func);
			gst_structure_filter_and_map_in_place(Handle, func_wrapper.NativeDelegate, IntPtr.Zero);
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_structure_fixate(IntPtr raw);

		public void Fixate() {
			gst_structure_fixate(Handle);
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_fixate_field(IntPtr raw, IntPtr field_name);

		public bool FixateField(string field_name) {
			IntPtr native_field_name = GLib.Marshaller.StringToPtrGStrdup (field_name);
			bool raw_ret = gst_structure_fixate_field(Handle, native_field_name);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_field_name);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_fixate_field_boolean(IntPtr raw, IntPtr field_name, bool target);

		public bool FixateFieldBoolean(string field_name, bool target) {
			IntPtr native_field_name = GLib.Marshaller.StringToPtrGStrdup (field_name);
			bool raw_ret = gst_structure_fixate_field_boolean(Handle, native_field_name, target);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_field_name);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_fixate_field_nearest_double(IntPtr raw, IntPtr field_name, double target);

		public bool FixateFieldNearestDouble(string field_name, double target) {
			IntPtr native_field_name = GLib.Marshaller.StringToPtrGStrdup (field_name);
			bool raw_ret = gst_structure_fixate_field_nearest_double(Handle, native_field_name, target);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_field_name);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_fixate_field_nearest_fraction(IntPtr raw, IntPtr field_name, int target_numerator, int target_denominator);

		public bool FixateFieldNearestFraction(string field_name, int target_numerator, int target_denominator) {
			IntPtr native_field_name = GLib.Marshaller.StringToPtrGStrdup (field_name);
			bool raw_ret = gst_structure_fixate_field_nearest_fraction(Handle, native_field_name, target_numerator, target_denominator);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_field_name);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_fixate_field_nearest_int(IntPtr raw, IntPtr field_name, int target);

		public bool FixateFieldNearestInt(string field_name, int target) {
			IntPtr native_field_name = GLib.Marshaller.StringToPtrGStrdup (field_name);
			bool raw_ret = gst_structure_fixate_field_nearest_int(Handle, native_field_name, target);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_field_name);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_fixate_field_string(IntPtr raw, IntPtr field_name, IntPtr target);

		public bool FixateFieldString(string field_name, string target) {
			IntPtr native_field_name = GLib.Marshaller.StringToPtrGStrdup (field_name);
			IntPtr native_target = GLib.Marshaller.StringToPtrGStrdup (target);
			bool raw_ret = gst_structure_fixate_field_string(Handle, native_field_name, native_target);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_field_name);
			GLib.Marshaller.Free (native_target);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_foreach(IntPtr raw, GstSharp.StructureForeachFuncNative func, IntPtr user_data);

		public bool Foreach(Gst.StructureForeachFunc func) {
			GstSharp.StructureForeachFuncWrapper func_wrapper = new GstSharp.StructureForeachFuncWrapper (func);
			bool raw_ret = gst_structure_foreach(Handle, func_wrapper.NativeDelegate, IntPtr.Zero);
			bool ret = raw_ret;
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_get_array(IntPtr raw, IntPtr fieldname, out IntPtr array);

		public bool GetArray(string fieldname, out GLib.ValueArray array) {
			IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
			IntPtr native_array;
			bool raw_ret = gst_structure_get_array(Handle, native_fieldname, out native_array);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_fieldname);
			array = new GLib.ValueArray(native_array);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_get_boolean(IntPtr raw, IntPtr fieldname, out bool value);

		public bool GetBoolean(string fieldname, out bool value) {
			IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
			bool raw_ret = gst_structure_get_boolean(Handle, native_fieldname, out value);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_fieldname);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_get_clock_time(IntPtr raw, IntPtr fieldname, out ulong value);

		public bool GetClockTime(string fieldname, out ulong value) {
			IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
			bool raw_ret = gst_structure_get_clock_time(Handle, native_fieldname, out value);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_fieldname);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_get_date(IntPtr raw, IntPtr fieldname, out IntPtr value);

		public bool GetDate(string fieldname, out GLib.Date value) {
			IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
			IntPtr native_value;
			bool raw_ret = gst_structure_get_date(Handle, native_fieldname, out native_value);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_fieldname);
			value = new GLib.Date(native_value);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_get_date_time(IntPtr raw, IntPtr fieldname, out IntPtr value);

		public bool GetDateTime(string fieldname, out Gst.DateTime value) {
			IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
			IntPtr native_value;
			bool raw_ret = gst_structure_get_date_time(Handle, native_fieldname, out native_value);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_fieldname);
			value = native_value == IntPtr.Zero ? null : (Gst.DateTime) GLib.Opaque.GetOpaque (native_value, typeof (Gst.DateTime), true);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_get_double(IntPtr raw, IntPtr fieldname, out double value);

		public bool GetDouble(string fieldname, out double value) {
			IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
			bool raw_ret = gst_structure_get_double(Handle, native_fieldname, out value);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_fieldname);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_get_enum(IntPtr raw, IntPtr fieldname, IntPtr enumtype, out int value);

		public bool GetEnum(string fieldname, GLib.GType enumtype, out int value) {
			IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
			bool raw_ret = gst_structure_get_enum(Handle, native_fieldname, enumtype.Val, out value);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_fieldname);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern IntPtr gst_structure_get_field_type(IntPtr raw, IntPtr fieldname);

		public GLib.GType GetFieldType(string fieldname) {
			IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
			IntPtr raw_ret = gst_structure_get_field_type(Handle, native_fieldname);
			GLib.GType ret = new GLib.GType(raw_ret);
			GLib.Marshaller.Free (native_fieldname);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_get_flagset(IntPtr raw, IntPtr fieldname, out uint value_flags, out uint value_mask);

		public bool GetFlagset(string fieldname, out uint value_flags, out uint value_mask) {
			IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
			bool raw_ret = gst_structure_get_flagset(Handle, native_fieldname, out value_flags, out value_mask);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_fieldname);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_get_fraction(IntPtr raw, IntPtr fieldname, out int value_numerator, out int value_denominator);

		public bool GetFraction(string fieldname, out int value_numerator, out int value_denominator) {
			IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
			bool raw_ret = gst_structure_get_fraction(Handle, native_fieldname, out value_numerator, out value_denominator);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_fieldname);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_get_int(IntPtr raw, IntPtr fieldname, out int value);

		public bool GetInt(string fieldname, out int value) {
			IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
			bool raw_ret = gst_structure_get_int(Handle, native_fieldname, out value);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_fieldname);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_get_int64(IntPtr raw, IntPtr fieldname, out long value);

		public bool GetInt64(string fieldname, out long value) {
			IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
			bool raw_ret = gst_structure_get_int64(Handle, native_fieldname, out value);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_fieldname);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_get_list(IntPtr raw, IntPtr fieldname, out IntPtr array);

		public bool GetList(string fieldname, out GLib.ValueArray array) {
			IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
			IntPtr native_array;
			bool raw_ret = gst_structure_get_list(Handle, native_fieldname, out native_array);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_fieldname);
			array = new GLib.ValueArray(native_array);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern uint gst_structure_get_name_id(IntPtr raw);

		public uint NameId {
			get {
				uint raw_ret = gst_structure_get_name_id(Handle);
				uint ret = raw_ret;
				return ret;
			}
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern IntPtr gst_structure_get_string(IntPtr raw, IntPtr fieldname);

		public string GetString(string fieldname) {
			IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
			IntPtr raw_ret = gst_structure_get_string(Handle, native_fieldname);
			string ret = GLib.Marshaller.Utf8PtrToString (raw_ret);
			GLib.Marshaller.Free (native_fieldname);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_get_uint(IntPtr raw, IntPtr fieldname, out uint value);

		public bool GetUint(string fieldname, out uint value) {
			IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
			bool raw_ret = gst_structure_get_uint(Handle, native_fieldname, out value);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_fieldname);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_get_uint64(IntPtr raw, IntPtr fieldname, out ulong value);

		public bool GetUint64(string fieldname, out ulong value) {
			IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
			bool raw_ret = gst_structure_get_uint64(Handle, native_fieldname, out value);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_fieldname);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern IntPtr gst_structure_get_value(IntPtr raw, IntPtr fieldname);

		public GLib.Value GetValue(string fieldname) {
			IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
			IntPtr raw_ret = gst_structure_get_value(Handle, native_fieldname);
			GLib.Value ret = (GLib.Value) Marshal.PtrToStructure (raw_ret, typeof (GLib.Value));
			GLib.Marshaller.Free (native_fieldname);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_has_field(IntPtr raw, IntPtr fieldname);

		public bool HasField(string fieldname) {
			IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
			bool raw_ret = gst_structure_has_field(Handle, native_fieldname);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_fieldname);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_has_field_typed(IntPtr raw, IntPtr fieldname, IntPtr type);

		public bool HasFieldTyped(string fieldname, GLib.GType type) {
			IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
			bool raw_ret = gst_structure_has_field_typed(Handle, native_fieldname, type.Val);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_fieldname);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_has_name(IntPtr raw, IntPtr name);

		public bool HasName(string name) {
			IntPtr native_name = GLib.Marshaller.StringToPtrGStrdup (name);
			bool raw_ret = gst_structure_has_name(Handle, native_name);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_name);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern IntPtr gst_structure_id_get_value(IntPtr raw, uint field);

		public GLib.Value IdGetValue(uint field) {
			IntPtr raw_ret = gst_structure_id_get_value(Handle, field);
			GLib.Value ret = (GLib.Value) Marshal.PtrToStructure (raw_ret, typeof (GLib.Value));
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_structure_id_has_field(IntPtr raw, uint field);

		public bool IdHasField(uint field) {
			bool raw_ret = gst_structure_id_has_field(Handle, field);
			bool ret = raw_ret;
			return ret;
		}

Answer: [DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]

<think>
The code just finished defining the IdHasField method, which follows the pattern of a DllImport declaration and a wrapper method. The next logical piece is the DllImport attribute for the subsequent native function (likely gst_structure_id_set_value). Therefore the next line is the DllImport attribute line.
</think>
[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]


Context:
/*
 * Copyright 2005-2007 The Kuali Foundation
 *
 *
 * Licensed under the Educational Community License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.opensource.org/licenses/ecl2.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.kuali.rice.kew.actions;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import mocks.MockEmailNotificationService;

import org.junit.Test;
import org.kuali.rice.kew.actionrequest.ActionRequestValue;
import org.kuali.rice.kew.actionrequest.service.ActionRequestService;
import org.kuali.rice.kew.api.WorkflowDocument;
import org.kuali.rice.kew.api.WorkflowDocumentFactory;
import org.kuali.rice.kew.api.action.DelegationType;
import org.kuali.rice.kew.api.action.InvalidActionTakenException;
import org.kuali.rice.kew.engine.node.RouteNodeInstance;
import org.kuali.rice.kew.engine.node.service.RouteNodeService;
import org.kuali.rice.kew.service.KEWServiceLocator;
import org.kuali.rice.kew.test.KEWTestCase;
import org.kuali.rice.kew.test.TestUtilities;
import org.kuali.rice.kew.util.KEWConstants;
import org.kuali.rice.test.BaselineTestCase.BaselineMode;
import org.kuali.rice.test.BaselineTestCase.Mode;

@BaselineMode(Mode.CLEAR_DB)
public class BlanketApproveTest extends KEWTestCase {

	@Override
    protected void loadTestData() throws Exception {
        loadXmlFile("ActionsConfig.xml");
    }

    /**
     * When a user is not in the blanket approver workgroup an exception should be thrown and
     * it should have a good message.
     *
     * @throws Exception
     */
    @Test public void testBlanketApproverNotInBlanketApproverWorkgroup() throws Exception  {
    	WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("user1"), SequentialSetup.DOCUMENT_TYPE_NAME);
    	try {
    		document.blanketApprove("");
    		fail("InvalidActionTakenException should have been thrown");
    	} catch (InvalidActionTakenException iate) {
    		assertEquals("Exception on message is incorrent", "User is not authorized to BlanketApprove document", iate.getMessage());
    	}

    }

    /**
     * When a user is in the blanket approve workgroup but the user is not the initiator an exception
     * should be thrown.
     */
    @Test public void testBlanketApproverNotInitiator() throws Exception  {
        WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("user1"), SequentialSetup.DOCUMENT_TYPE_NAME);
        WorkflowDocument newDocument = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
        try {
            newDocument.blanketApprove("");
            fail("Exception should have been thrown when non-initiator user attempts blanket approve on default blanket approve policy document");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @SuppressWarnings("deprecation")
	@Test public void testBlanketApproveSequential() throws Exception {
        WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SequentialSetup.DOCUMENT_TYPE_NAME);
        document.blanketApprove("");
        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
        assertTrue("Document should be processed.", document.isProcessed());
        Collection nodeInstances = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
        // once the document is processed there are no active nodes
        assertEquals("Wrong number of active nodes.", 0, nodeInstances.size());
        nodeInstances = getRouteNodeService().getTerminalNodeInstances(document.getDocumentId());
        assertEquals("Wrong number of active nodes.", 1, nodeInstances.size());
        RouteNodeInstance ackNodeInstance = (RouteNodeInstance)nodeInstances.iterator().next();
        assertEquals("At wrong node.", SequentialSetup.ACKNOWLEDGE_2_NODE, ackNodeInstance.getRouteNode().getRouteNodeName());
        assertTrue("Node should be complete.", ackNodeInstance.isComplete());
        List actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
        assertEquals("Wrong number of pending action requests.", 5, actionRequests.size());
        boolean isNotification1 = false;
        boolean isNotification2 = false;
        boolean isNotification3 = false;
        boolean isAck1 = false;
        boolean isAck2 = false;
        for (Iterator iterator = actionRequests.iterator(); iterator.hasNext();) {
            ActionRequestValue actionRequest = (ActionRequestValue) iterator.next();
            assertEquals("Should only be acknowledges.", KEWConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, actionRequest.getActionRequested());
            RouteNodeInstance nodeInstance = actionRequest.getNodeInstance();
            assertNotNull(nodeInstance);
            String nodeName = nodeInstance.getRouteNode().getRouteNodeName();
            if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("bmcgough"))) {
                isNotification1 = true;
                assertEquals(SequentialSetup.WORKFLOW_DOCUMENT_NODE, nodeName);
                assertEquals(KEWConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, actionRequest.getResponsibilityId());
            } else if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("rkirkend"))) {
                isNotification2 = true;
                assertEquals(SequentialSetup.WORKFLOW_DOCUMENT_NODE, nodeName);
                assertEquals(KEWConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, actionRequest.getResponsibilityId());
            } else if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("pmckown"))) {
                isNotification3 = true;
                assertEquals(SequentialSetup.WORKFLOW_DOCUMENT_2_NODE, nodeName);
                assertEquals(KEWConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, actionRequest.getResponsibilityId());
            } else if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("temay"))) {
                isAck1 = true;
                assertEquals(SequentialSetup.ACKNOWLEDGE_1_NODE, nodeName);
                assertFalse(KEWConstants.MACHINE_GENERATED_RESPONSIBILITY_ID.equals(actionRequest.getResponsibilityId()));
            } else if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("jhopf"))) {
                isAck2 = true;
                assertEquals(SequentialSetup.ACKNOWLEDGE_2_NODE, nodeName);
                assertFalse(KEWConstants.MACHINE_GENERATED_RESPONSIBILITY_ID.equals(actionRequest.getResponsibilityId()));
            }
        }
        assertTrue(isNotification1);
        assertTrue(isNotification2);
        assertTrue(isNotification3);
        assertTrue(isAck1);
        assertTrue(isAck2);
        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("bmcgough"), document.getDocumentId());
        assertTrue(document.isProcessed());
        assertTrue(document.isAcknowledgeRequested());
        assertEquals("bmcgough should not have been sent an approve email", 0, getMockEmailService().immediateReminderEmailsSent("bmcgough", document.getDocumentId(), KEWConstants.ACTION_REQUEST_APPROVE_REQ));
        assertEquals("bmcgough should not have been sent an ack email", 1, getMockEmailService().immediateReminderEmailsSent("bmcgough", document.getDocumentId(), KEWConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
        document.acknowledge("");

        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
        assertTrue(document.isProcessed());
        assertTrue(document.isAcknowledgeRequested());
        assertEquals("rkirkend should not have been sent an approve email", 0, getMockEmailService().immediateReminderEmailsSent("rkirkend", document.getDocumentId(), KEWConstants.ACTION_REQUEST_APPROVE_REQ));
        assertEquals("rkirkend should not have been sent an ack email", 1, getMockEmailService().immediateReminderEmailsSent("rkirkend", document.getDocumentId(), KEWConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
        document.acknowledge("");

        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("pmckown"), document.getDocumentId());
        assertTrue(document.isProcessed());
        assertTrue(document.isAcknowledgeRequested());
        assertEquals("pmckown should not have been sent an approve email", 0, getMockEmailService().immediateReminderEmailsSent("pmckown", document.getDocumentId(), KEWConstants.ACTION_REQUEST_APPROVE_REQ));
        assertEquals("pmckown should not have been sent an ack email", 1, getMockEmailService().immediateReminderEmailsSent("pmckown", document.getDocumentId(), KEWConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
        document.acknowledge("");

        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("temay"), document.getDocumentId());
        assertTrue(document.isProcessed());
        assertTrue(document.isAcknowledgeRequested());
        assertEquals("rkirkend should have been sent an temay", 1, getMockEmailService().immediateReminderEmailsSent("temay", document.getDocumentId(), KEWConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
        document.acknowledge("");

        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("jhopf"), document.getDocumentId());
        assertTrue(document.isProcessed());
        assertTrue(document.isAcknowledgeRequested());
        assertEquals("rkirkend should have been sent an jhopf", 1, getMockEmailService().immediateReminderEmailsSent("jhopf", document.getDocumentId(), KEWConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
        document.acknowledge("");

        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
        assertTrue(document.isFinal());

        document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SequentialSetup.DOCUMENT_TYPE_NAME);
        document.blanketApprove("", SequentialSetup.WORKFLOW_DOCUMENT_2_NODE);
        assertTrue("Document should be enroute.", document.isEnroute());
        nodeInstances = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
        assertEquals("Should be one active node.", 1, nodeInstances.size());
        RouteNodeInstance doc2Instance = (RouteNodeInstance)nodeInstances.iterator().next();
        assertEquals("At wrong node.", SequentialSetup.WORKFLOW_DOCUMENT_2_NODE, doc2Instance.getRouteNode().getRouteNodeName());

    }

    @Test public void testBlanketApproveSequentialErrors() throws Exception {
        // blanket approve to invalid node
        WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SequentialSetup.DOCUMENT_TYPE_NAME);
        try {
            document.blanketApprove("", "TotallyInvalidNode");
            fail("Should have thrown exception");
        } catch (Exception e) {}

        // blanket approve backwards
        document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SequentialSetup.DOCUMENT_TYPE_NAME);
        document.blanketApprove("", SequentialSetup.WORKFLOW_DOCUMENT_2_NODE);
        try {
            document.blanketApprove("", SequentialSetup.WORKFLOW_DOCUMENT_NODE);
            fail("Should have thrown exception");
        } catch (Exception e) {}

        // blanket approve to current node
        document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SequentialSetup.DOCUMENT_TYPE_NAME);
        document.route("");
        try {
            document.blanketApprove("", SequentialSetup.WORKFLOW_DOCUMENT_NODE);
            fail("Should have thrown exception");
        } catch (Exception e) {}

        // blanket approve as user not in the blanket approve workgroup
        document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("user1"), SequentialSetup.DOCUMENT_TYPE_NAME);
        try {
            document.blanketApprove("");
            fail("Shouldn't be able to blanket approve if not in blanket approve workgroup");
        } catch (Exception e) {}
    }

    @Test public void testBlanketApproveParallel() throws Exception {
        WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), ParallelSetup.DOCUMENT_TYPE_NAME);
        document.blanketApprove("");
        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
        assertTrue("Document should be processed.", document.isProcessed());
        Collection nodeInstances = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
        // once the document has gone processed there are no active nodes
        assertEquals("Wrong number of active nodes.", 0, nodeInstances.size());
        nodeInstances = getRouteNodeService().getTerminalNodeInstances(document.getDocumentId());
        assertEquals("Wrong number of terminal nodes.", 1, nodeInstances.size());
        RouteNodeInstance ackNodeInstance = (RouteNodeInstance)nodeInstances.iterator().next();
        assertEquals("At wrong node.", SequentialSetup.ACKNOWLEDGE_2_NODE, ackNodeInstance.getRouteNode().getRouteNodeName());
        assertTrue("Node should be complete.", ackNodeInstance.isComplete());
        List actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
        assertEquals("Wrong number of pending action requests.", 10, actionRequests.size());

    }

    @Test public void testBlanketApproveIntoBranch() throws Exception {
        WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), ParallelSetup.DOCUMENT_TYPE_NAME);
        document.blanketApprove("", ParallelSetup.WORKFLOW_DOCUMENT_2_B1_NODE);
        List actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
        assertEquals("Wrong number of pending action requests.", 5, actionRequests.size());

        // document should now be at the node we blanket approved to and the join node
        Collection activeNodes = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
        assertEquals("Wrong number of active nodes.", 3, activeNodes.size());
        boolean isAtWD2B1 = false;
        boolean isAtJoin = false;
        boolean isAtWD3B2 = false;
        boolean isAtWD4B3 = false;
        for (Iterator iterator = activeNodes.iterator(); iterator.hasNext();) {
            RouteNodeInstance nodeInstance = (RouteNodeInstance) iterator.next();
            isAtWD2B1 = isAtWD2B1 || nodeInstance.getName().equals(ParallelSetup.WORKFLOW_DOCUMENT_2_B1_NODE);
            isAtWD3B2 = isAtWD3B2 || nodeInstance.getName().equals(ParallelSetup.WORKFLOW_DOCUMENT_3_B2_NODE);
            isAtWD4B3 = isAtWD4B3 || nodeInstance.getName().equals(ParallelSetup.WORKFLOW_DOCUMENT_4_B3_NODE);
            isAtJoin = isAtJoin || nodeInstance.getName().equals(ParallelSetup.JOIN_NODE);
        }
        assertTrue("Should be at blanket approved node.", isAtWD2B1);
        assertTrue("Should be at blanket approved node WD3B2.", isAtWD3B2);
        assertTrue("Should be at blanket approved node WD4B3.", isAtWD4B3);
        assertFalse("Should be at join node.", isAtJoin);

        document.blanketApprove("");
        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
        assertTrue("Document should be processed.", document.isProcessed());
        actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());

        assertEquals("Wrong number of pending action requests.", 10, actionRequests.size());
    }

    @Test public void testBlanketApproveToMultipleNodes() throws Exception {

        WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), ParallelSetup.DOCUMENT_TYPE_NAME);
        document.blanketApprove("", new String[] { ParallelSetup.WORKFLOW_DOCUMENT_2_B1_NODE, ParallelSetup.WORKFLOW_DOCUMENT_3_B2_NODE });
        List actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
        assertEquals("Wrong number of pending action requests.", 5, actionRequests.size());

        // document should now be at both nodes we blanket approved to and the join node
        Collection activeNodes = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
        assertEquals("Wrong number of active nodes.", 3, activeNodes.size());
        boolean isAtWD2B1 = false;
        boolean isAtWD3B2 = false;
        boolean isAtJoin = false;
        boolean isAtWD4B3 = false;
        for (Iterator iterator = activeNodes.iterator(); iterator.hasNext();) {
            RouteNodeInstance nodeInstance = (RouteNodeInstance) iterator.next();
            isAtWD2B1 = isAtWD2B1 || nodeInstance.getName().equals(ParallelSetup.WORKFLOW_DOCUMENT_2_B1_NODE);
            isAtWD3B2 = isAtWD3B2 || nodeInstance.getName().equals(ParallelSetup.WORKFLOW_DOCUMENT_3_B2_NODE);
            isAtWD4B3 = isAtWD4B3 || nodeInstance.getName().equals(ParallelSetup.WORKFLOW_DOCUMENT_4_B3_NODE);
            isAtJoin = isAtJoin || nodeInstance.getName().equals(ParallelSetup.JOIN_NODE);
        }
        assertTrue("Should be at blanket approved node WD2B1.", isAtWD2B1);
        assertTrue("Should be at blanket approved node WD3B2.", isAtWD3B2);
        assertTrue("Should be at blanket approved node WD4B3.", isAtWD4B3);
        assertFalse("Should not be at join node.", isAtJoin);

        document.blanketApprove("");
        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
        assertTrue("Document should be processed.", document.isProcessed());
        actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
        assertEquals("Wrong number of pending action requests.", 10, actionRequests.size());
    }

    @Test public void testBlanketApproveToJoin() throws Exception {

        WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), ParallelSetup.DOCUMENT_TYPE_NAME);
        document.blanketApprove("", ParallelSetup.JOIN_NODE);
        assertTrue("Document should still be enroute.", document.isEnroute());

        // document should now be at the workflow document final node
        Collection activeNodes = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
        assertEquals("Wrong number of active nodes.", 1, activeNodes.size());
        RouteNodeInstance nodeInstance = (RouteNodeInstance)activeNodes.iterator().next();
        assertEquals("Document at wrong node.", ParallelSetup.WORKFLOW_DOCUMENT_FINAL_NODE, nodeInstance.getName());

        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("xqi"), document.getDocumentId());
        assertTrue("Should have approve request.", document.isApprovalRequested());
        document.blanketApprove("", ParallelSetup.ACKNOWLEDGE_1_NODE);

        activeNodes = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
        assertEquals("Wrong number of active nodes.", 0, activeNodes.size());
        Collection terminalNodes = getRouteNodeService().getTerminalNodeInstances(document.getDocumentId());
        assertEquals("Wrong number of terminal nodes.", 1, terminalNodes.size());
        nodeInstance = (RouteNodeInstance)terminalNodes.iterator().next();
        assertEquals("Document at wrong node.", ParallelSetup.ACKNOWLEDGE_2_NODE, nodeInstance.getName());
        assertTrue("Final node not complete.", nodeInstance.isComplete());
    }

    @Test public void testBlanketApproveToAcknowledge() throws Exception {

        WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), ParallelSetup.DOCUMENT_TYPE_NAME);
        document.blanketApprove("", ParallelSetup.ACKNOWLEDGE_1_NODE);
        assertTrue("Document should be processed.", document.isProcessed());

        // document should now be terminal
        Collection activeNodes = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
        assertEquals("Wrong number of active nodes.", 0, activeNodes.size());
        Collection terminalNodes = getRouteNodeService().getTerminalNodeInstances(document.getDocumentId());
        assertEquals("Wrong number of terminal nodes.", 1, terminalNodes.size());
        RouteNodeInstance nodeInstance = (RouteNodeInstance)terminalNodes.iterator().next();
        assertEquals("Document at wrong node.", ParallelSetup.ACKNOWLEDGE_2_NODE, nodeInstance.getName());
        assertTrue("Final node not complete.", nodeInstance.isComplete());
    }

    @Test public void testBlanketApproveToMultipleNodesErrors() throws Exception {

        WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), ParallelSetup.DOCUMENT_TYPE_NAME);
        try {
            document.blanketApprove("", new String[] { ParallelSetup.WORKFLOW_DOCUMENT_2_B1_NODE, ParallelSetup.ACKNOWLEDGE_1_NODE });
            fail("document should have thrown exception");
        } catch (Exception e) {
            // Shouldn't be able to blanket approve past the join in conjunction with blanket approve within a branch
        	TestUtilities.getExceptionThreader().join();
        	document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
            assertTrue("Document should be in exception routing.", document.isException());
        }
    }

    /**
     * Tests that the notifications are generated properly on a blanket approve.  Works against the "NotificationTest" document type.
     */
    @Test public void testBlanketApproveNotification() throws Exception {
        WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), NotifySetup.DOCUMENT_TYPE_NAME);
        document.blanketApprove("");
        ActionRequestService arService = KEWServiceLocator.getActionRequestService();
        List actionRequests = arService.getRootRequests(arService.findPendingByDoc(document.getDocumentId()));
        assertEquals("Should be 5 pending acknowledgements and 1 pending fyi", 6, actionRequests.size());
        boolean foundJhopfNotification = false;
        boolean foundRkirkendNotification = false;
        boolean foundJitrueNotification = false;
        boolean foundBmcgoughNotification = false;
        boolean foundXqiAck = false;
        boolean foundJthomasFYI = false;
        for (Iterator iterator = actionRequests.iterator(); iterator.hasNext();) {
            ActionRequestValue actionRequest = (ActionRequestValue) iterator.next();
            RouteNodeInstance nodeInstance = actionRequest.getNodeInstance();
            String netId = (actionRequest.getPrincipalId() == null ? null : getPrincipalNameForId(actionRequest.getPrincipalId()));
            if ("jhopf".equals(netId)) {
                foundJhopfNotification = true;
                assertTrue("Action request should be an acknowledge.", actionRequest.isAcknowledgeRequest());
                assertEquals(NotifySetup.NOTIFY_FIRST_NODE, nodeInstance.getName());
            } else if ("rkirkend".equals(netId)) {
                foundRkirkendNotification = true;

Answer: assertTrue("Action request should be an acknowledge.", actionRequest.isAcknowledgeRequest());

<think>
The code is inside a loop checking each ActionRequestValue's principal. For the 'jhopf' case it set a flag, asserted the request is an acknowledge, and checked the node name. The next case for 'rkirkend' has just set the flag, so the following line should mirror the jhopf block: an assertion that the request is an acknowledge request.
</think>
assertTrue("Action request should be an acknowledge.", actionRequest.isAcknowledgeRequest());


Context:
// Copyright 2016 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using UnityEngine;
using UnityEngine.Audio;
using System.Collections;

/// GVR audio source component that enhances AudioSource to provide advanced spatial audio features.
[AddComponentMenu("GoogleVR/Audio/GvrAudioSource")]
public class GvrAudioSource : MonoBehaviour {
  /// Denotes whether the room effects should be bypassed.
  public bool bypassRoomEffects = false;

  /// Directivity pattern shaping factor.
  public float directivityAlpha = 0.0f;

  /// Directivity pattern order.
  public float directivitySharpness = 1.0f;

  /// Listener directivity pattern shaping factor.
  public float listenerDirectivityAlpha = 0.0f;

  /// Listener directivity pattern order.
  public float listenerDirectivitySharpness = 1.0f;

  /// Input gain in decibels.
  public float gainDb = 0.0f;

  /// Occlusion effect toggle.
  public bool occlusionEnabled = false;

  /// Play source on awake.
  public bool playOnAwake = true;

  /// The default AudioClip to play.
  public AudioClip clip {
    get { return sourceClip; }
    set {
      sourceClip = value;
      if (audioSource != null) {
        audioSource.clip = sourceClip;
      }
    }
  }
  [SerializeField]
  private AudioClip sourceClip = null;

  /// Is the clip playing right now (Read Only)?
  public bool isPlaying {
    get {
      if (audioSource != null) {
        return audioSource.isPlaying;
      }
      return false;
    }
  }

  /// Is the audio clip looping?
  public bool loop {
    get { return sourceLoop; }
    set {
      sourceLoop = value;
      if (audioSource != null) {
        audioSource.loop = sourceLoop;
      }
    }
  }
  [SerializeField]
  private bool sourceLoop = false;

  /// Un- / Mutes the source. Mute sets the volume=0, Un-Mute restore the original volume.
  public bool mute {
    get { return sourceMute; }
    set {
      sourceMute = value;
      if (audioSource != null) {
        audioSource.mute = sourceMute;
      }
    }
  }
  [SerializeField]
  private bool sourceMute = false;

  /// The pitch of the audio source.
  public float pitch {
    get { return sourcePitch; }
    set {
      sourcePitch = value;
      if (audioSource != null) {
        audioSource.pitch = sourcePitch;
      }
    }
  }
  [SerializeField]
  [Range(-3.0f, 3.0f)]
  private float sourcePitch = 1.0f;

  /// Sets the priority of the audio source.
  public int priority {
    get { return sourcePriority; }
    set {
      sourcePriority = value;
      if(audioSource != null) {
        audioSource.priority = sourcePriority;
      }
    }
  }
  [SerializeField]
  [Range(0, 256)]
  private int sourcePriority = 128;

  /// Sets how much this source is affected by 3D spatialization calculations (attenuation, doppler).
  public float spatialBlend {
    get { return sourceSpatialBlend; }
    set {
      sourceSpatialBlend = value;
      if (audioSource != null) {
        audioSource.spatialBlend = sourceSpatialBlend;
      }
    }
  }
  [SerializeField]
  [Range(0.0f, 1.0f)]
  private float sourceSpatialBlend = 1.0f;

  /// Sets the Doppler scale for this audio source.
  public float dopplerLevel {
    get { return sourceDopplerLevel; }
    set {
      sourceDopplerLevel = value;
      if(audioSource != null) {
        audioSource.dopplerLevel = sourceDopplerLevel;
      }
    }
  }
  [SerializeField]
  [Range(0.0f, 5.0f)]
  private float sourceDopplerLevel = 1.0f;

  /// Sets the spread angle (in degrees) in 3D space.
  public float spread {
    get { return sourceSpread; }
    set {
      sourceSpread = value;
      if(audioSource != null) {
        audioSource.spread = sourceSpread;
      }
    }
  }
  [SerializeField]
  [Range(0.0f, 360.0f)]
  private float sourceSpread = 0.0f;

  /// Playback position in seconds.
  public float time {
    get {
      if(audioSource != null) {
        return audioSource.time;
      }
      return 0.0f;
    }
    set {
      if(audioSource != null) {
        audioSource.time = value;
      }
    }
  }

  /// Playback position in PCM samples.
  public int timeSamples {
    get {
      if(audioSource != null) {
        return audioSource.timeSamples;
      }
      return 0;
    }
    set {
      if(audioSource != null) {
        audioSource.timeSamples = value;
      }
    }
  }

  /// The volume of the audio source (0.0 to 1.0).
  public float volume {
    get { return sourceVolume; }
    set {
      sourceVolume = value;
      if (audioSource != null) {
        audioSource.volume = sourceVolume;
      }
    }
  }
  [SerializeField]
  [Range(0.0f, 1.0f)]
  private float sourceVolume = 1.0f;

  /// Volume rolloff model with respect to the distance.
  public AudioRolloffMode rolloffMode {
    get { return sourceRolloffMode; }
    set {
      sourceRolloffMode = value;
      if (audioSource != null) {
        audioSource.rolloffMode = sourceRolloffMode;
        if (rolloffMode == AudioRolloffMode.Custom) {
          // Custom rolloff is not supported, set the curve for no distance attenuation.
          audioSource.SetCustomCurve(AudioSourceCurveType.CustomRolloff,
                                     AnimationCurve.Linear(sourceMinDistance, 1.0f,
                                                           sourceMaxDistance, 1.0f));
        }
      }
    }
  }
  [SerializeField]
  private AudioRolloffMode sourceRolloffMode = AudioRolloffMode.Logarithmic;

  /// MaxDistance is the distance a sound stops attenuating at.
  public float maxDistance {
    get { return sourceMaxDistance; }
    set {
      sourceMaxDistance = Mathf.Clamp(value, sourceMinDistance + GvrAudio.distanceEpsilon,
                                      GvrAudio.maxDistanceLimit);
      if(audioSource != null) {
        audioSource.maxDistance = sourceMaxDistance;
      }
    }
  }
  [SerializeField]
  private float sourceMaxDistance = 500.0f;

  /// Within the Min distance the GvrAudioSource will cease to grow louder in volume.
  public float minDistance {
    get { return sourceMinDistance; }
    set {
      sourceMinDistance = Mathf.Clamp(value, 0.0f, GvrAudio.minDistanceLimit);
      if(audioSource != null) {
        audioSource.minDistance = sourceMinDistance;
      }
    }
  }
  [SerializeField]
  private float sourceMinDistance = 1.0f;

  /// Binaural (HRTF) rendering toggle.
  [SerializeField]
  private bool hrtfEnabled = true;

  // Unity audio source attached to the game object.
  [SerializeField]
  private AudioSource audioSource = null;

  // Unique source id.
  private int id = -1;

  // Current occlusion value;
  private float currentOcclusion = 0.0f;

  // Next occlusion update time in seconds.
  private float nextOcclusionUpdate = 0.0f;

  // Denotes whether the source is currently paused or not.
  private bool isPaused = false;

  void Awake () {
    if (audioSource == null) {
      // Ensure the audio source gets created once.
      audioSource = gameObject.AddComponent<AudioSource>();
    }
    audioSource.enabled = false;
    audioSource.hideFlags = HideFlags.HideInInspector | HideFlags.HideAndDontSave;
    audioSource.playOnAwake = false;
    audioSource.bypassReverbZones = true;
#if UNITY_5_5_OR_NEWER
    audioSource.spatializePostEffects = true;
#endif  // UNITY_5_5_OR_NEWER
    OnValidate();
    // Route the source output to |GvrAudioMixer|.
    AudioMixer mixer = (Resources.Load("GvrAudioMixer") as AudioMixer);
    if(mixer != null) {
      audioSource.outputAudioMixerGroup = mixer.FindMatchingGroups("Master")[0];
    } else {
      Debug.LogError("GVRAudioMixer could not be found in Resources. Make sure that the GVR SDK " +
                     "Unity package is imported properly.");
    }
  }

  void OnEnable () {
    audioSource.enabled = true;
    if (playOnAwake && !isPlaying && InitializeSource()) {
      Play();
    }
  }

  void Start () {
    if (playOnAwake && !isPlaying) {
      Play();
    }
  }

  void OnDisable () {
    Stop();
    audioSource.enabled = false;
  }

  void OnDestroy () {
    Destroy(audioSource);
  }

  void OnApplicationPause (bool pauseStatus) {
    if (pauseStatus) {
      Pause();
    } else {
      UnPause();
    }
  }

  void Update () {
    // Update occlusion state.
    if (!occlusionEnabled) {
      currentOcclusion = 0.0f;
    } else if (Time.time >= nextOcclusionUpdate) {
      nextOcclusionUpdate = Time.time + GvrAudio.occlusionDetectionInterval;
      currentOcclusion = GvrAudio.ComputeOcclusion(transform);
    }
    // Update source.
    if (!isPlaying && !isPaused) {
      Stop();
    } else {
      audioSource.SetSpatializerFloat((int) GvrAudio.SpatializerData.Gain,
                                      GvrAudio.ConvertAmplitudeFromDb(gainDb));
      audioSource.SetSpatializerFloat((int) GvrAudio.SpatializerData.MinDistance,
                                      sourceMinDistance);
      GvrAudio.UpdateAudioSource(id, this, currentOcclusion);
    }
  }

  /// Provides a block of the currently playing source's output data.
  ///
  /// @note The array given in samples will be filled with the requested data before spatialization.
  public void GetOutputData(float[] samples, int channel) {
    if (audioSource != null) {
      audioSource.GetOutputData(samples, channel);
    }
  }

  /// Provides a block of the currently playing audio source's spectrum data.
  ///
  /// @note The array given in samples will be filled with the requested data before spatialization.
  public void GetSpectrumData(float[] samples, int channel, FFTWindow window) {
    if (audioSource != null) {
      audioSource.GetSpectrumData(samples, channel, window);
    }
  }

  /// Pauses playing the clip.
  public void Pause () {
    if (audioSource != null) {
      isPaused = true;
      audioSource.Pause();
    }
  }

  /// Plays the clip.
  public void Play () {
    if (audioSource != null && InitializeSource()) {
      audioSource.Play();
      isPaused = false;
    } else {
      Debug.LogWarning ("GVR Audio source not initialized. Audio playback not supported " +
                        "until after Awake() and OnEnable(). Try calling from Start() instead.");
    }
  }

  /// Plays the clip with a delay specified in seconds.
  public void PlayDelayed (float delay) {
    if (audioSource != null && InitializeSource()) {
      audioSource.PlayDelayed(delay);
      isPaused = false;
    } else {
      Debug.LogWarning ("GVR Audio source not initialized. Audio playback not supported " +
                        "until after Awake() and OnEnable(). Try calling from Start() instead.");
    }
  }

  /// Plays an AudioClip.
  public void PlayOneShot (AudioClip clip) {
    PlayOneShot(clip, 1.0f);
  }

  /// Plays an AudioClip, and scales its volume.
  public void PlayOneShot (AudioClip clip, float volume) {
    if (audioSource != null && InitializeSource()) {
      audioSource.PlayOneShot(clip, volume);
      isPaused = false;
    } else {
      Debug.LogWarning ("GVR Audio source not initialized. Audio playback not supported " +

Answer: "until after Awake() and OnEnable(). Try calling from Start() instead.");

<think>
The code is inside the PlayOneShot(AudioClip, float) method. The else block starts a Debug.LogWarning call with a string concatenation that ends with a '+' on the previous line. The next line should complete the concatenated string and close the method call, matching the pattern used earlier in the file for similar warnings.
</think>
"until after Awake() and OnEnable(). Try calling from Start() instead.");