'val',
            'sentAs'  => 'vim',
            'filters' => ['strtoupper']
        ]);
        $model = new Parameter();
        $response = new Response(200, [], \GuzzleHttp\Psr7\stream_for('bar'));
        $result = new Result();
        $result = $location->before($result, $response, $model);
        $result = $location->visit($result, $response, $parameter);
        $result = $location->after($result, $response, $model);
        $this->assertEquals('BAR', $result['val']);
    }
    /**
     * @group ResponseLocation
     */
    public function testVisitsAdditionalProperties()
    {
        $location = new XmlLocation();
        $parameter = new Parameter();
        $model = new Parameter(['additionalProperties' => ['location' => 'xml']]);
        $response = new Response(200, [], \GuzzleHttp\Psr7\stream_for('bar'));
        $result = new Result();
        $result = $location->before($result, $response, $parameter);
        $result = $location->visit($result, $response, $parameter);
        $result = $location->after($result, $response, $model);
        $this->assertEquals('bar', $result['vim']);
    }
    /**
     * @group ResponseLocation
     */
    public function testEnsuresFlatArraysAreFlat()
    {
        $param = new Parameter([
            'location' => 'xml',
            'name'     => 'foo',
            'type'     => 'array',
            'items'    => ['type' => 'string'],
        ]);
        $xml = 'barbaz';
        $this->xmlTest($param, $xml, ['foo' => ['bar', 'baz']]);
        $this->xmlTest($param, 'bar', ['foo' => ['bar']]);
    }
    public function xmlDataProvider()
    {
        $param = new Parameter([
            'location' => 'xml',
            'name'     => 'Items',
            'type'     => 'array',
            'items'    => [
                'type'       => 'object',
                'name'       => 'Item',
                'properties' => [
                    'Bar' => ['type' => 'string'],
                    'Baz' => ['type' => 'string'],
                ],
            ],
        ]);
        return [
            [$param, '- 1
- 2', [
                'Items' => [
                    ['Bar' => 1],
                    ['Bar' => 2],
                ],
            ]],
            [$param, '
- 1', [
                'Items' => [
                    ['Bar' => 1],
                ]
            ]],
            [$param, '', [
                'Items' => [],
            ]]
        ];
    }
    /**
     * @dataProvider xmlDataProvider
     * @group ResponseLocation
     */
    public function testEnsuresWrappedArraysAreInCorrectLocations($param, $xml, $expected)
    {
        $location = new XmlLocation();
        $model = new Parameter();
        $response = new Response(200, [], \GuzzleHttp\Psr7\stream_for($xml));
        $result = new Result();
        $result = $location->before($result, $response, $param);
        $result = $location->visit($result, $response, $param);
        $result = $location->after($result, $response, $model);
        $this->assertEquals($expected, $result->toArray());
    }
    /**
     * @group ResponseLocation
     */
    public function testCanRenameValues()
    {
        $param = new Parameter([
            'name'     => 'TerminatingInstances',
            'type'     => 'array',
            'location' => 'xml',
            'sentAs'   => 'instancesSet',
            'items'    => [
                'name'       => 'item',
                'type'       => 'object',
                'sentAs'     => 'item',
                'properties' => [
                    'InstanceId'    => [
                        'type'   => 'string',
                        'sentAs' => 'instanceId',
                    ],
                    'CurrentState'  => [
                        'type'       => 'object',
                        'sentAs'     => 'currentState',
                        'properties' => [
                            'Code' => [
                                'type'   => 'numeric',
                                'sentAs' => 'code',
                            ],
                            'Name' => [
                                'type'   => 'string',
                                'sentAs' => 'name',
                            ],
                        ],
                    ],
                    'PreviousState' => [
                        'type'       => 'object',
                        'sentAs'     => 'previousState',
                        'properties' => [
                            'Code' => [
                                'type'   => 'numeric',
                                'sentAs' => 'code',
                            ],
                            'Name' => [
                                'type'   => 'string',
                                'sentAs' => 'name',
                            ],
                        ],
                    ],
                ],
            ]
        ]);
        $xml = '
- 
                        i-3ea74257
                        
                            32shutting-down16running
';
        $this->xmlTest($param, $xml, [
            'TerminatingInstances' => [
                [
                    'InstanceId'    => 'i-3ea74257',
                    'CurrentState'  => [
                        'Code' => '32',
                        'Name' => 'shutting-down',
                    ],
                    'PreviousState' => [
                        'Code' => '16',
                        'Name' => 'running',
                    ],
                ],
            ],
        ]);
    }
    /**
     * @group ResponseLocation
     */
    public function testCanRenameAttributes()
    {
        $param = new Parameter([
            'name'     => 'RunningQueues',
            'type'     => 'array',
            'location' => 'xml',
            'items'    => [
                'type'       => 'object',
                'sentAs'     => 'item',
                'properties' => [
                    'QueueId'       => [
                        'type'   => 'string',
                        'sentAs' => 'queue_id',
                        'data'   => [
                            'xmlAttribute' => true,
                        ],
                    ],
                    'CurrentState'  => [
                        'type'       => 'object',
                        'properties' => [
                            'Code' => [
                                'type'   => 'numeric',
                                'sentAs' => 'code',
                                'data'   => [
                                    'xmlAttribute' => true,
                                ],
                            ],
                            'Name' => [
                                'sentAs' => 'name',
                                'data'   => [
                                    'xmlAttribute' => true,
                                ],
                            ],
                        ],
                    ],
                    'PreviousState' => [
                        'type'       => 'object',
                        'properties' => [
                            'Code' => [
                                'type'   => 'numeric',
                                'sentAs' => 'code',
                                'data'   => [
                                    'xmlAttribute' => true,
                                ],
                            ],
                            'Name' => [
                                'sentAs' => 'name',
                                'data'   => [
                                    'xmlAttribute' => true,
                                ],
                            ],
                        ],
                    ],
                ],
            ]
        ]);
        $xml = '- 
                        
                        
                    ';
        $this->xmlTest($param, $xml, [
            'RunningQueues' => [
                [
                    'QueueId'       => 'q-3ea74257',
                    'CurrentState'  => [
                        'Code' => '32',
                        'Name' => 'processing',
                    ],
                    'PreviousState' => [
                        'Code' => '16',
                        'Name' => 'wait',
                    ],
                ],
            ],
        ]);
    }
    /**
     * @group ResponseLocation
     */
    public function testAddsEmptyArraysWhenValueIsMissing()
    {
        $param = new Parameter([
            'name'     => 'Foo',
            'type'     => 'array',
            'location' => 'xml',
            'items'    => [
                'type'       => 'object',
                'properties' => [
                    'Baz' => ['type' => 'array'],
                    'Bar' => [
                        'type'       => 'object',
                        'properties' => [
                            'Baz' => ['type' => 'array'],
                        ],
                    ],
                ],
            ],
        ]);
        $xml = '';
        $this->xmlTest($param, $xml, [
            'Foo' => [
                [
                    'Bar' => [],
                ]
            ],
        ]);
    }
    /**
     * @group issue-399, ResponseLocation
     * @link  https://github.com/guzzle/guzzle/issues/399
     */
    public function testDiscardingUnknownProperties()
    {
        $param = new Parameter([
            'name'                 => 'foo',
            'type'                 => 'object',
            'additionalProperties' => false,
            'properties'           => [
                'bar' => [
                    'type' => 'string',
                    'name' => 'bar',
                ],
            ],
        ]);
        $xml = '
            
                
                    15
                    discard me
                
            
        ';
        $this->xmlTest($param, $xml, [
            'foo' => [
                'bar' => 15
            ]
        ]);
    }
    /**
     * @group issue-399, ResponseLocation
     * @link  https://github.com/guzzle/guzzle/issues/399
     */
    public function testDiscardingUnknownPropertiesWithAliasing()
    {
        $param = new Parameter([
            'name'                 => 'foo',
            'type'                 => 'object',
            'additionalProperties' => false,
            'properties'           => [
                'bar' => [
                    'name'   => 'bar',
                    'sentAs' => 'baz',
                ],
            ],
        ]);
        $xml = '
            
                
                    15
                    discard me
                
            
        ';
        $this->xmlTest($param, $xml, [
            'foo' => [
                'bar' => 15,
            ],
        ]);
    }
    /**
     * @group ResponseLocation
     */
    public function testProcessingOfNestedAdditionalProperties()
    {
        $param = new Parameter([
            'name'                 => 'foo',
            'type'                 => 'object',
            'additionalProperties' => true,
            'properties'           => [
                'bar' => [
                    'name'   => 'bar',
                    'sentAs' => 'baz',
                ],
                'nestedNoAdditional'  => [
                    'type' => 'object',
                    'additionalProperties' => false,
                    'properties' => [
                        'id' => [
                            'type' => 'integer',
                        ],
                    ],
                ],
                'nestedWithAdditional' => [
                    'type' => 'object',
                    'additionalProperties' => true,
                ],
                'nestedWithAdditionalSchema' => [
                    'type' => 'object',
                    'additionalProperties' => [
                        'type'  => 'array',
                        'items' => [
                            'type' => 'string',
                        ],
                    ],
                ],
            ],
        ]);
        $xml = '
            
                
                    15
                    include me
                    
                        15
                        discard me
                    
                    
                        15
                        include me
- 1
- 2
- 3
- A
- B
- C';
        $this->xmlTest($param, $xml, [
            'foo' => [
                'bar' => '15',
                'additional' => 'include me',
                'nestedNoAdditional' => [
                    'id' => '15',
                ],
                'nestedWithAdditional' => [
                    'id'         => '15',
                    'additional' => 'include me',
                ],
                'nestedWithAdditionalSchema' => [
                    'arrayA' => ['1', '2', '3'],
                    'arrayB' => ['A', 'B', 'C'],
                ],
            ],
        ]);
    }
    /**
     * @group ResponseLocation
     */
    public function testConvertsMultipleAssociativeElementsToArray()
    {
        $param = new Parameter([
            'name'                 => 'foo',
            'type'                 => 'object',
            'additionalProperties' => true,
        ]);
        $xml = '
            
                
                    15
                    25
                    hi
                    test
                    
                
            
        ';
        $this->xmlTest($param, $xml, [
            'foo' => [
                'baz' => ['15', '25'],
                'bar' => 'hi',
                'bam' => [
                    'test',
                    ['@attributes' => ['attr' => 'hi']]
                ]
            ]
        ]);
    }
    /**
     * @group ResponseLocation
     */
    public function testUnderstandsNamespaces()
    {
        $param = new Parameter([
            'name'     => 'nstest',
            'type'     => 'array',
            'location' => 'xml',
            'items'    => [
                'name'       => 'item',
                'type'       => 'object',
                'sentAs'     => 'item',
                'properties' => [
                    'id'           => [
                        'type' => 'string',
                    ],
                    'isbn:number'  => [
                        'type' => 'string',
                    ],
                    'meta'         => [
                        'type'       => 'object',
                        'sentAs'     => 'abstract:meta',
                        'properties' => [
                            'foo' => [
                                'type' => 'numeric',
                            ],
                            'bar' => [
                                'type'       => 'object',
                                'properties' =>[
                                    'attribute' => [
                                        'type' => 'string',
                                        'data' => [
                                            'xmlAttribute' => true,
                                            'xmlNs'        => 'abstract',
                                        ],
                                    ],
                                ],
                            ],
                        ],
                    ],
                    'gamma'        => [
                        'type'                 => 'object',
                        'data'                 => [
                            'xmlNs' => 'abstract',
                        ],
                        'additionalProperties' => true,
                    ],
                    'nonExistent'  => [
                        'type'                 => 'object',
                        'data'                 => [
                            'xmlNs' => 'abstract',
                        ],
                        'additionalProperties' => true,
                    ],
                    'nonExistent2' => [
                        'type'                 => 'object',
                        'additionalProperties' => true,
                    ],
                ],
            ],
        ]);
        $xml = '
- 
                        101
                        1568491379
                        
                            10
                            
                        
                        
                            bar
                        
                    
- 
                        102
                        1568491999
                        
                            20
                            
                        
                        
                            baz
                        
                    ';
        $this->xmlTest($param, $xml, [
            'nstest' => [
                [
                    'id'          => '101',
                    'isbn:number' => 1568491379,
                    'meta'        => [
                        'foo' => 10,
                        'bar' => [
                            'attribute' => 'foo',
                        ],
                    ],
                    'gamma'       => [
                        'foo' => 'bar',
                    ],
                ],
                [
                    'id'          => '102',
                    'isbn:number' => 1568491999,
                    'meta'        => [
                        'foo' => 20,
                        'bar' => [
                            'attribute' => 'bar'
                        ],
                    ],
                    'gamma'       => [
                        'foo' => 'baz',
                    ],
                ],
            ],
        ]);
    }
    /**
     * @group ResponseLocation
     */
    public function testCanWalkUndefinedPropertiesWithNamespace()
    {
        $param = new Parameter([
            'name'     => 'nstest',
            'type'     => 'array',
            'location' => 'xml',
            'items'    => [
                'name' => 'item',
                'type' => 'object',
                'sentAs' => 'item',
                'additionalProperties' => [
                    'type' => 'object',
                    'data' => [
                        'xmlNs' => 'abstract'
                    ],
                ],
                'properties' => [
                    'id' => [
                        'type' => 'string',
                    ],
                    'isbn:number' => [
                        'type' => 'string',
                    ],
                ],
            ],
        ]);
        $xml = '
- 
                        101
                        1568491379
                        
                            10
                            baz
                        
                    
- 
                        102
                        1568491999
                        
                            20
                            foo
                        
                    ';
        $this->xmlTest($param, $xml, [
            'nstest' => [
                [
                    'id'          => '101',
                    'isbn:number' => 1568491379,
                    'meta'        => [
                        'foo' => 10,
                        'bar' => 'baz',
                    ],
                ],
                [
                    'id'          => '102',
                    'isbn:number' => 1568491999,
                    'meta'        => [
                        'foo' => 20,
                        'bar' => 'foo',
                    ],
                ],
            ]
        ]);
    }
    /**
     * @group ResponseLocation
     */
    public function testCanWalkSimpleArrayWithNamespace()
    {
        $param = new Parameter([
            'name'     => 'nstest',
            'type'     => 'array',
            'location' => 'xml',
            'items'    => [
                'type'   => 'string',
                'sentAs' => 'number',
                'data'   => [
                    'xmlNs' => 'isbn'
                ],
            ],
        ]);
        $xml = '
            
                
                    1568491379
                    1568491999
                    1568492999
                
            
        ';
        $this->xmlTest($param, $xml, [
            'nstest' => [
                1568491379,
                1568491999,
                1568492999,
            ],
        ]);
    }
    /**
     * @group ResponseLocation
     */
    public function testCanWalkSimpleArrayWithNamespace2()
    {
        $param = new Parameter([
            'name'     => 'nstest',
            'type'     => 'array',
            'location' => 'xml',
            'items'    => [
                'type'   => 'string',
                'sentAs' => 'isbn:number',
            ]
        ]);
        $xml = '
            
                
                    1568491379
                    1568491999
                    1568492999
                
            
        ';
        $this->xmlTest($param, $xml, [
            'nstest' => [
                1568491379,
                1568491999,
                1568492999,
            ],
        ]);
    }
    private function xmlTest(Parameter $param, $xml, $expected)
    {
        $location = new XmlLocation();
        $model = new Parameter();
        $response = new Response(200, [], \GuzzleHttp\Psr7\stream_for($xml));
        $result = new Result();
        $result = $location->before($result, $response, $param);
        $result = $location->visit($result, $response, $param);
        $result = $location->after($result, $response, $model);
        $this->assertEquals($expected, $result->toArray());
    }
}